301. Remove Invalid Parentheses
括号匹配题
题干:
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
Note: The input string may contain letters other than the parentheses ( and ).
解释:
问删除的最小括号的数目,使得字符串有效。
思考:
字符串类型题有一个通用的trick,就是可以先统计一遍左括号和右括号的个数。至于这道题,我们首先要从字符中去除有效的部分,怎么去除呢?如果left的个数不为0,然后此时又遇到了一个right,那么直接将left-1即可。如果left已经为0,那么right+1,注意在前面的right和后面的left是无法抵消的,这样最后就可以得到多余的right和left括号了 知道了要删除的括号的最小数量之后,就开始从头到尾dfs即可,删除对应的括号。注意使用start来避免ab,ba类型的重复。
答案:
class Solution:
def valid(self, string):
left, right = 0, 0
for c in string:
if c == '(':
left += 1
elif c == ')':
right += 1
if right > left:
return False
return True
def removeInvalidParentheses(self, s):
# 虽然可能存在其他字符,但对于算法几乎没有影响
# 首先,找到最少应该抛弃的括号的数量
# 然后,尝试所有可能的抛弃
left, right = 0, 0 # 最少的前括号和后括号的抛弃数量
for c in s:
if c == '(':
left += 1
elif c == ')':
if left > 0:
left -= 1
else:
right += 1
if left + right == len(s):
return ['']
elif left + right == 0:
return [s]
ans = set()
# temp是我们当前得到的结果
# 其中l,r记录temp中前、后括号的数量
# front, back是剩余丢弃括号的数量
def dfs(front, back, string, l, r, temp):
if r > l or (front + back > 0 and string == ''):
return
if front == 0 and back == 0:
cur = temp + string
if cur not in ans and self.valid(cur):
ans.add(cur)
return
if string[0] == '(':
if front > 0:
dfs(front-1, back, string[1:], l, r, temp)
dfs(front, back, string[1:], l+1, r, temp+'(')
elif string[0] == ')':
if back > 0:
dfs(front, back-1, string[1:], l, r, temp)
dfs(front, back, string[1:], l, r+1, temp+')')
else:
dfs(front, back, string[1:], l, r, temp+string[0])
dfs(left, right, s, 0, 0, '')
return list(ans)