思路与算法
题目中所要求最少删除,这样的描述正是广度优先搜索算法应用的场景,并且题目也要求我们输出所有的结果。我们在进行广度优先搜索时每一轮删除字符串中的 11 个括号,直到出现合法匹配的字符串为止,此时进行轮转的次数即为最少需要删除括号的个数。
我们进行广度优先搜索时,每次保存上一轮搜索的结果,然后对上一轮已经保存的结果中的每一个字符串尝试所有可能的删除一个括号的方法,然后将保存的结果进行下一轮搜索。在保存结果时,我们可以利用哈希表对上一轮生成的结果去重,从而提高效率。
class Solution:
def removeInvalidParentheses(self, s: str) -> List[str]:
def checkValid(str, lmask, left, rmask, right):
pos1, pos2 = 0, 0
cnt = 0
for i in range(len(str)):
if pos1 < len(left) and i == left[pos1]:
if lmask & (1 << pos1) == 0:
cnt += 1
pos1 += 1
elif pos2 < len(right) and i == right[pos2]:
if rmask & (1 << pos2) == 0:
cnt -= 1
if cnt < 0:
return False
pos2 += 1
return cnt == 0
def recoverStr(lmask, left, rmask, right):
pos1, pos2 = 0, 0
res = ""
for i in range(len(s)):
if pos1 < len(left) and i == left[pos1]:
if lmask & (1 << pos1) == 0:
res += s[i]
pos1 += 1
elif pos2 < len(right) and i == right[pos2]:
if rmask & (1 << pos2) == 0:
res += s[i]
pos2 += 1
else:
res += s[i]
return res
def countBit(x):
res = 0
while x != 0:
x = x & (x - 1)
res += 1
return res
lremove, rremove = 0, 0
left, right = [], []
ans = []
cnt = set()
for i in range(len(s)):
if s[i] == '(':
left.append(i)
lremove += 1
elif s[i] == ')':
right.append(i)
if lremove == 0:
rremove += 1
else:
lremove -= 1
m, n = len(left), len(right)
maskArr1, maskArr2 = [], []
for i in range(1 << m):
if countBit(i) != lremove:
continue
maskArr1.append(i)
for i in range(1 << n):
if countBit(i) != rremove:
continue
maskArr2.append(i)
for mask1 in maskArr1:
for mask2 in maskArr2:
if checkValid(s, mask1, left, mask2, right):
cnt.add(recoverStr(mask1, left, mask2, right))
return [val for val in cnt