分析
简单的括号check函数
然后一开始想的是状态压缩判断
但是这样会遍历到很多无效情况
因此,我们可以考虑从原始s一个个括号删除(因为是最小删除)
这样一旦遇到满足的删除个数立即返回即可,不需要额外多余的遍历
无脑状态压缩
class Solution:
def removeInvalidParentheses(self, s: str) -> List[str]:
# 状态压缩
maxLength = 0
ans = set()
n = len(s)
# 字母的位置不能删
alpha = []
for i in range(n):
if s[i] in ascii_lowercase:
alpha.append(i)
#print(alpha)
# 检查是否有效
def check(s):
# 辅助栈
st = []
for c in s:
if c in ascii_lowercase:
continue
if st and st[-1] == '(' and c == ')':
st.pop()
else:
st.append(c)
#print(st)
return len(st) == 0
# 状态压缩(但是对字母是不必要的)
for i in range(1 << n):
si = bin(i)[2:].zfill(n)
# 保证不删掉字母
flag = True
for j in alpha:
if si[j] == '0':
flag = False
break
if not flag:
continue
now = ''
for j, v in enumerate(si):
if v == '1':
now += s[j]
if len(now) < maxLength:
continue
if check(now) and len(now) == maxLength:
ans.add(now)
elif check(now) and len(now) > maxLength:
maxLength = len(now)
ans = set()
ans.add(now)
return list(ans)
bfs解决最小删除问题(从原str开始删括号)
class Solution:
def removeInvalidParentheses(self, s: str) -> List[str]:
# 检查是否有效
def check(s):
# 辅助栈
st = []
for c in s:
if c in ascii_lowercase:
continue
if st and st[-1] == '(' and c == ')':
st.pop()
else:
st.append(c)
#print(st)
return len(st) == 0
ans = []
# 使用bfs逐个括号删除(忽略字母干扰)
curSet = set([s])
while curSet:
# 如果当前set中有合法的就放进去ans
ans = [s for s in curSet if check(s)]
if ans:
return ans
nextSet = set()
# 针对当前set的每一个砍掉一个括号
for s in curSet:
for i, c in enumerate(s):
if c == '(' or c == ')':
nextSet.add(s[:i] + s[i + 1:])
curSet = nextSet
总结
最小删除问题由于是原s的子串
因此可以根据上一个删除的一位位删除
这样每一层的bfs都是保证元素个数相同的所有情况
然后一旦有合法的就立即返回
同时不会被无效的字母干扰