forked from tcandzq/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRemoveInvalidParentheses.py
More file actions
131 lines (109 loc) · 3.87 KB
/
RemoveInvalidParentheses.py
File metadata and controls
131 lines (109 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/2 23:23
# @Author : tc
# @File : RemoveInvalidParentheses.py
"""
题号 301 删除无效的括号
删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
说明: 输入可能包含了除 ( 和 ) 以外的字符。
示例 1:
输入: "()())()"
输出: ["()()()", "(())()"]
示例 2:
输入: "(a)())()"
输出: ["(a)()()", "(a())()"]
示例 3:
输入: ")("
输出: [""]
这是dfs除了在树遍历中的其他应用,要好好看。毫无思路
1.定义一个括号是否合法的函数(可以用栈实现);
2.
解法2和leetcode40题 组合总和II的解法很像
"""
from typing import List
class Solution:
# 解法1 没看懂
def removeInvalidParentheses(self, s: str) -> List[str]:
# 找字符串最长有效括号的长度
def longestVaildParentheses(s: str):
res = 0
stack = []
for a in s:
if a == "(":
stack.append("(")
elif a == ")":
if stack:
res += 2
stack.pop()
return res
def helper(s, left_p, right_p, open, tmp):
# 当都小于0 都不满足条件
if left_p < 0 or right_p < 0 or open < 0:
return
# s剩余的括号都不够组成的
if s.count("(") < left_p or s.count(")") < right_p:
return
if not s:
# 输出
if left_p == 0 and right_p == 0 and open == 0:
res.add(tmp)
return
if s[0] == "(":
# 用 "("
helper(s[1:], left_p - 1, right_p, open + 1, tmp + "(")
# 不用 "("
helper(s[1:], left_p, right_p, open, tmp)
elif s[0] == ")":
# 用 ")"
helper(s[1:], left_p, right_p - 1, open - 1, tmp + ")")
# 不用 ")"
helper(s[1:], left_p, right_p, open, tmp)
else:
helper(s[1:], left_p, right_p, open, tmp + s[0])
l = longestVaildParentheses(s)
res = set()
# 因为l是最长的, 所以左括号和右括号各一半, 再用open表示左右括号抵消多少
helper(s, l // 2, l // 2, 0, "")
return list(res)
# 解法2
def removeInvalidParentheses2(self, s: str) -> List[str]:
res = []
left = 0
right = 0
for char in s: # 统计不合法的左括号和右括号的数量
if char == '(':
left += 1
if char == ')':
if left > 0:
left -= 1
else:
right += 1
def check(s: str) -> bool: # 检验括号是否有效
cnt = 0
for char in s:
if char == '(':
cnt += 1
if char == ')':
cnt -= 1
if cnt < 0:
return False
return cnt == 0
def dfs(s, st, left, right):
if left == 0 and right == 0:
if check(s): # 如果左边和右边非法的括号已经删除结束,且剩下的字符串s是有效的
res.append(s)
return
for i in range(st, len(s)):
if i - 1 >= st and s[i] == s[i - 1]:
continue
if left > 0 and s[i] == '(':
dfs(s[0:i]+s[i+1:i+1 + len(s) - i - 1], i, left - 1,right)
if right > 0 and s[i] == ')':
dfs(s[0:i]+s[i+1:i+1 + len(s) - i - 1], i, left, right - 1)
dfs(s,0,left,right)
return res
if __name__ == '__main__':
s = "()())()"
solution = Solution()
print(solution.removeInvalidParentheses2(s))