解法
跟没有*
的时候原理差不多,贪心,不断统计待匹配的左括号(
的数量left
,能匹配的时候尽量匹配
*
可以被分成三类:
- 未转化的:它既可以转化成
(
,也可以转化成)
- 转化成
)
的:它可以通过跟一个遇不到左括号的)
交换,重新变成未转化的
假设现在是这样的场景(A*B)
,其中那个左括号是之前和*
匹配的那个左括号,而右括号是一个遇不到左括号的右括号。
首先,A
和B
肯定是合法括号串。因为A
里的左括号必须要在A
里匹配完了,才能轮到(A*B)
里这个左括号跟星号匹配。同理,由于(A*B)
里的右括号是遇不到左括号的右括号,所以显然B
里的左括号也已完全匹配,所以B
也是合法串。
那么,如果我们把(A*B)
里这个左括号跟当前这个遇不到左括号的右括号匹配,那么中间这个*
就是未转化的了。 - 转化成
(
的:这部分的*
相当于定死了,也不能转回去了,也不可能被当成(
用了
所以我们可以记录前两类*
的数量:unused
和right
- 每次遇到左括号
(
,left
加1 - 每次遇到右括号
)
:- 如果还有未匹配的左括号,匹配
- 否则,如果有转成
)
的*
,把它变成未转化的 - 否则,如果还有未转化的
*
,它把转化成左括号(
- 否则,这个右括号无法匹配,返回
False
- 每次遇到
*
:- 如果有未匹配的左括号
(
,匹配 - 否则未转化的
*
个数加一
- 如果有未匹配的左括号
class Solution:
def checkValidString(self, s: str) -> bool:
left = unused = right = 0
for c in s:
if c=='(':
left += 1
elif c==')':
if left:
left -= 1
elif right:
right -= 1
unused += 1
elif unused:
unused -= 1
else:
return False
else:
if left:
left -= 1
right += 1
else:
unused += 1
return left==0