Day16:Valid Parenthesis String
问题描述:
给定一个仅包含三种类型的字符的字符串:'(',')'和'*',编写一个函数来检查此字符串是否有效。我们通过以下规则定义字符串的有效性:
任何左括号'('必须具有对应的右括号')'。
任何右括号')'必须具有对应的左括号'('。
左括号'('必须位于相应的右括号')'之前。
'*'可被视为单个右括号')'或单个左括号'('或一个空字符串。空字符串也是有效的。
Example:
Example 1:
Input: "()"
Output: True
Example 2:
Input: "(*)"
Output: True
Example 3:
Input: "(*))"
Output: True
解法一:
设置双栈,左括号栈和start栈
遇到左括号,将左括号的位置放入左栈中,
遇到*,将*的位置放入start栈中
如果遇到右括号,则从左括号栈中顶出一个,若左括号栈为空,则从start栈中顶出一个,若start栈也为空,则返回False
遍历一遍后,若左括号栈不为空,且start栈为空,则返回false
若左括号栈不为空,且start栈不为空,则在依次遍历这两个栈,依次顶出一个元素,若start栈的位置在左括号栈之前则返回False。
在上述遍历也完成后,若左括号栈还是有元素则说明左括号多了,返回False,否则返回True.
class Solution:
def checkValidString(self, s: str) -> bool:
for i in range(len(s)):
print(i)
print(left,start)
if s[i] == '(':
left.append(i)
elif s[i] == '*':
start.append(i)
else:
if len(left) == 0 and len(start) == 0:
return False
if len(left) != 0:
left.pop()
else:
start.pop()
while(len(left) != 0 and len(start) !=0):
l = left.pop()
s = start.pop()
if l > s:
return False
return len(left) == 0
时间复杂度为O(n),空间复杂度为O(N).
解法二:
设置左右两个变量left,right,遍历两次字符串。第一次正向遍历:将认为是‘(’,所以如果遇到和‘(’则left 加1,否则减1,若在过程中left 小于0,则返回false,遍历结束后,若left = 0,则返回True,否则left > 0,还需要进行反向遍历,因为有可能多余的‘(’是‘’,所以反向遍历:这次将‘’认为是‘)’,对right变量的操作跟之前一样,最后若right >= 0 返回True.因为大于0和之前的left > 0对应上了,说明有多余的*,*可以认为是空字符。
class Solution:
def checkValidString(self, s: str) -> bool:
left , right = 0,0
for i in range(len(s)):
if s[i] == '(' or s[i] == '*':
left += 1
else:
left -= 1
if left < 0:
return False
if left == 0:
return True
for i in range(len(s) -1 , -1 ,-1):
if s[i] == ')' or s[i] == '*':
right += 1
else:
right -= 1
if right < 0:
return False
return True
时间复杂度为O(n),空间复杂度为O(1).
解法三:
暴力破解,递归方法,设置辅助函数,里面参数有当前递归开始的位置,以及当前左括号的个数,从当前位置开始遍历字符串,如果遇到左括号则记录变量加1,如果遇到右括号且记录变量大于0,则记录变量减1,否则返回false,如果遇到*,则从下一个位置开始新的递归,将*作为左括号,右括号,和空的情况都遍历到,将这三种情况通过or连接起来,只要有一种情况是True就行,最后看记录变量是否为0.
不过这种算法复杂度太高,leetcode好像不通过。
class Solution:
def checkValidString(self, s: str) -> bool:
return self.helper(s,0,0)
def helper(self,s,start,count):
if count < 0:
return False
for i in range(start,len(s)):
if s[i] == '(':
count += 1
elif s[i] == ')':
if count > 0:
count -= 1
else:
return False
else:
return self.helper(s,i+1,count) or self.helper(s,i + 1,count + 1) or self.helper(s,i + 1,count - 1)
return count == 0
解法四:
还有一种解法,据说是论坛上第一的算法,但是我还没怎么看懂,所以先贴出来别人的解析链接,留待后续再看。