301. Remove Invalid Parentheses
删去特定括号使s
变得 valid,需要删的左括号/右括号数量是恒定的(可以遍历计算出来),只是可能有多种删除位置的选择,最终目标就是找出所有有效的删除位置选择。
每一个位置都可以选择删除或者保留,但暴力遍历的时间复杂度是O(2^n)。根据已确认字符串cur
的状态,可以排除一些选择(剪枝),最坏情况仍然O(2^n),但实际小很多。
有点参考Q20,基于左右括号计数的backtracking
.
class Solution(object):
def removeInvalidParentheses(self, s: str) -> List[str]:
res = set()
l, redundant_l, redundant_r = 0, 0, 0
# 计算多余(须删去)的左右括号
for i in range(len(s)):
if s[i] == '(': l += 1
elif s[i] == ')':
if l > 0: l -= 1
else: redundant_r += 1
redundant_l = l
self.backtracking(0, 0, s, 0, '', res, redundant_l, redundant_r)
return res if res else ['']
def backtracking(self, l, r, s, idx, cur, res, redundant_l, redundant_r):
# 到末尾了,判断当前string是不是valid
if idx == len(s):
if l == r and redundant_l==redundant_r==0:
res.add(cur)
return
if s[idx] == '(':
# 如果还有左括号多余 -> 删去当前左括号
if redundant_l > 0:
self.backtracking(l, r, s, idx+1, cur, res, redundant_l-1, redundant_r)
self.backtracking(l+1, r, s, idx+1, cur+'(', res, redundant_l, redundant_r)
elif s[idx] == ')':
# 还有右括号多余
## 情况1: 当前左括号大于等于右括号
## 情况2: 当前还没有左括号
## -> 删去新的右括号
if redundant_r > 0 and (l==0 or l>=r):
self.backtracking(l, r, s, idx+1, cur, res, redundant_l, redundant_r-1)
# 当前左括号比右括号多 -> 保留新的右括号
if l > r:
self.backtracking(l, r+1, s, idx+1, cur+')', res, redundant_l, redundant_r)
# 非括号字符
else:
self.backtracking(l, r, s, idx+1, cur+s[idx], res, redundant_l, redundant_r)
Last updated
Was this helpful?