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(")("))