301. 删除无效的括号
原始题目链接:https://leetcode.cn/problems/remove-invalid-parentheses/
给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。
返回所有可能的结果。答案可以按 任意顺序 返回。
示例 1:
输入:s = “()())()”
输出:[“(())()”,“()()()”]
示例 2:
输入:s = “(a)())()”
输出:[“(a())()”,“(a)()()”]
示例 3:
输入:s = “)(”
输出:[“”]
提示:
1 <= s.length <= 25
s 由小写英文字母以及括号 ‘(’ 和 ‘)’ 组成
s 中至多含 20 个括号
解题思路:
先统计多余的左右括号数量,然后递归的删除多余的括号,剩下的保留。
代码实现:
class Solution:
def removeInvalidParentheses(self, s: str) -> List[str]:
# 统计s中多余的(即左右不匹配的)左右括号数量
l = r = 0
for c in s:
if c == '(':
l += 1
elif c == ')':
if l:
l -= 1
else:
r += 1
ans = []
@lru_cache(None)
def dfs(idx, cur_left, cur_right, del_left, del_right, path):
# 递归函数dfs: 从idx位置开始,删除掉多余的左、右括号或者保留当前的字符
# cur_left,cur_right分别是统计当前的左右括号数量
# del_left,del_right是统计当前删掉的左右括号个数
# 如果遍历到的位置和s长度相等,即没有多余的左右括号
if idx == len(s):
if not del_left and not del_right:
ans.append(path)
return
# 如果要当前的右括号比要删除的左括号多,或者要删除的左右括号数小于0
if cur_right > cur_left or del_left < 0 or del_right < 0:
return
c = s[idx]
# 先删除上一个函数统计的多余的左右括号数
if c == '(':
dfs(idx + 1, cur_left, cur_right, del_left - 1, del_right, path)
elif c == ')':
dfs(idx + 1, cur_left, cur_right, del_left, del_right - 1, path)
# 递归下一个位置
dfs(idx + 1, cur_left + int(c == '('), cur_right + int(c == ')'), del_left, del_right, path + c)
dfs(0, 0, 0, l, r, "")
return ans
参考文献:
https://leetcode.cn/problems/remove-invalid-parentheses/solution/python-ji-yi-hua-dfs-by-himymben-5b18/