动态规划法
新建一个与字符串相同长度的全0数组dp,数组表示字符串当前为匹配到的最大valid字符串长度
class Solution1:
def longestValidParentheses(self, s: str) -> int:
n = 0
dp = [0 for _ in range(len(s))]
sr = [string for string in s]
for i in range(1,len(s)):
if sr[i]==')':
if sr[i-1] == '(':
dp[i] = (dp[i-2] if i>=2 else 0) + 2 ###如果位置大于2,就加上前面匹配的子字符串长度
elif i-dp[i-1]>0 and sr[i-dp[i-1]-1]=='(': ###如果没有匹配,则向前搜索,在前面匹配的最大子字符串之前是否匹配
dp[i] =( dp[i-dp[i-1]-2] if (i-dp[i-1])>=2 else 0) +2+dp[i-1] #
n = max(n,dp[i]) #更新最大值
return n
###堆栈法:新建一个列表,并传入-1作为起始匹配位置,遍历字符串,遇到(将索引压入栈中,遇到)弹
###出栈顶表示匹配上一个(,再进行判断,若栈为空,说明已经无匹配对象,此时传入当前)的索引作为起始匹配位置
class Solution2:
def longestValidParentheses(self, s: str) -> int:
n = 0
stack = []
stack.append(-1)
for i in range(len(s)):
if s[i]=='(':
stack.append(i)
else:
stack.pop()
if not stack:
stack.append(i)
else:
n = max(n,i-stack[-1])
return n
节省空间的算法
创建两个数记录遇到的(和)的数目,正向遍历字符串,如果左右数相同则更新子字符串长度,如果右数大于左数,说明字符串匹配失败,重置左右数,接着再反向遍历一遍。
####左遍历是匹配右边有冗余的情况,如()),同理右匹配是匹配左边有冗余的情况,(()
class Solution:
def longestValidParentheses(self, s: str) -> int:
left = 0
right = 0
n = 0
for i in s:
if i=="(":
left +=1
else:
right+=1
if left ==right:
n = max(n,left+right)
elif right > left :
left = 0
right = 0
left = 0
right = 0
for i in reversed(s):
if i == ")":
right += 1
else:
left += 1
if left ==right:
n = max(n,left+right)
elif right < left :
left = 0
right = 0
return n