LeetCode 301. Remove Invalid Parentheses

本文探讨了一种高效算法,用于移除字符串中使括号序列无效的最小数量的括号,确保剩余序列的有效性。通过深度优先搜索(DFS)或广度优先搜索(BFS),并结合栈的数据结构,算法能在O(2^n*n)的时间复杂度内找到所有可能的解决方案。特别地,文章介绍了如何将问题规模从原始长度n减少到非法括号的数量,显著提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 ).

Example 1:

Input: "()())()"
Output: ["()()()", "(())()"]

Example 2:

Input: "(a)())()"
Output: ["(a)()()", "(a())()"]

Example 3:

Input: ")("
Output: [""]

---------------------------------------------------------------------------------------------------------

这题看了官方题解是崩溃的,代码特别长。。。

先想怎么判断是一个字符串是否合法,用个栈,这是容易想到的。但是用栈不合法的情况无非是,某个位置右括号比左括号多。当然最终左括号也有可能比右括号多。当右括号比左括号多的情况出现时,应该删除哪一个呢?这时脑子陷入眩晕。。

快速换个思路,暴力做,用DFS或者BFS把每个括号删除,然后判断是否合法,这样会有2^len*O(len)的复杂度

下面的思路是想了很久才想明白的,把2^len*O(len)里的len降低一些,或者说把len降低一些。回到最开始眩晕的问题,当右括号比左括号多的情况出现时,应该删除哪一个呢?如果是连续的右括号,删除连续中的某一个都一样。但是对于非连续右括号&右括号比左括号多的情况下,其中任意一个非连续右括号被删除都有可能出现新的局面。这是把len变成n的关键,其中n是非法右括号的个数。

另外,也有可能出现因为左括号比右括号多非法的情况,按照上面的情况再想一遍,刚好是把从左到右遍历改成了从右向左遍历。利用对称性,可以把第一阶段的结果都翻转,左括号和右括号互换,再来一遍。

这个思路代码很简洁而且很快:

class Solution:
    def bfs(self, layer, pars):
        layers = [layer, set()]
        c, n = 0, 1
        while (layers[c]):
            for cur in layers[c]:
                sta = 0
                for i, ch in enumerate(cur):
                    if (ch == pars[0]):
                        sta += 1
                    elif (ch == pars[1]):
                        sta -= 1
                    if (sta < 0):
                        for j in range(i + 1):
                            if ((j < i and cur[j] == pars[1] and cur[j + 1] != pars[1]) or j == i):
                                layers[n].add(cur[:j] + cur[j + 1:])
                        break #bug1: forget
            if (len(layers[n]) == 0):
                return {item[::-1] for item in layers[c]}
            else:
                layers[c].clear()
                c, n = n, c

    def removeInvalidParentheses(self, s: str):
        layer1 = self.bfs({s}, ['(', ')'])
        layer2 = self.bfs(layer1, [')', '('])
        return list(layer2)


s = Solution()
print(s.removeInvalidParentheses(")("))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值