2021-10-27

题目:删除无效括号

给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。

返回所有可能的结果。答案可以按 任意顺序 返回。

示例 1:

输入:s = “()())()”
输出:["(())()","()()()"]
示例 2:

输入:s = “(a)())()”
输出:["(a())()","(a)()()"]
示例 3:

输入:s = “)(”
输出:[""]

背景知识

**1.有效的「括号」:**题目输入的字符串由一系列「左括号」和「右括号」组成,但是有一些额外的括号,使得括号不能正确配对。对于括号配对规则如果还不太清楚的读者,可以先完成问题「20. 有效的括号」。
2.可以一次遍历计算出多余的「左括号」和「右括号」:
根据括号匹配规则和根据求解「22. 括号生成」的经验,我们知道:如果当前遍历到的「左括号」的数目严格小于「右括号」的数目则表达式无效。因此,我们可以遍历一次输入字符串,统计「左括号」和「右括号」出现的次数。
当遍历到「左括号」的时候:
「左括号」数量加 11。
当遍历到「右括号」的时候:
如果此时「左括号」的数量不为 00,因为「右括号」可以与之前遍历到的「左括号」匹配,此时「左括号」出现的次数 -1−1;
如果此时「左括号」的数量为 00,「右括号」数量加 11。
通过这样的计数规则,得到的「左括号」和「右括号」的数量就是各自最少应该删除的数量。

代码

class Solution:
    def removeInvalidParentheses(self, s: str) -> List[str]:
        res = []
        lremove, rremove = 0, 0
        for c in s:
            if c == '(':
                lremove += 1
            elif c == ')':
                if lremove == 0:
                    rremove += 1
                else:
                    lremove -= 1

        def isValid(str):
            cnt = 0
            for c in str:
                if c == '(':
                    cnt += 1
                elif c == ')':
                    cnt -= 1
                    if cnt < 0:
                        return False
            return cnt == 0

        def helper(s, start, lcount, rcount, lremove, rremove):
            if lremove == 0 and rremove == 0:
                if isValid(s):
                    res.append(s)
                return

            for  i in range(start, len(s)):
                if i > start and s[i] == s[i - 1]:
                    continue
                # 如果剩余的字符无法满足去掉的数量要求,直接返回
                if lremove + rremove > len(s) - i:
                    break
                # 尝试去掉一个左括号
                if lremove > 0 and s[i] == '(':
                    helper(s[:i] + s[i + 1:], i, lcount, rcount, lremove - 1, rremove);
                # 尝试去掉一个右括号
                if rremove > 0 and s[i] == ')':
                    helper(s[:i] + s[i + 1:], i, lcount, rcount, lremove, rremove - 1);
                # 统计当前字符串中已有的括号数量
                if s[i] == ')':
                    lcount += 1
                elif s[i] == ')':
                    rcount += 1
                # 当前右括号的数量大于左括号的数量则为非法,直接返回.
                if rcount > lcount:
                    break

        helper(s, 0, 0, 0, lremove, rremove)
        return res


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值