难度:困难
题目描述:
思路总结:啥都别说了,官方题解复制机来了。本文给出动态规划和栈的Python解法。两种方法的时空复杂度都是O(n)原文地址
题解一:
(暴力法)说是暴力法,还是用到了栈,把时间复杂度降到了O(n^2),空间复杂度为O(n),顶多用掉长度为n的栈。
note:看了下代码,还是想象中的暴力法,栈只是用在了判断是否是有效括号的函数上,暂时不做了。
题解一结果:
题解二:(动态规划)
class Solution:
def longestValidParentheses(self, s: str) -> int:
#思路:最长子串很容易让人联想到滑动窗口、DP等名词。
#滑动窗口没法用,动态规划肯定可以,但是状态转移方程比较复杂。(当我没说)
#两个转移方程:1.dp[i]=dp[i-2]+2 if s[i]=')' and s[i-1]='('
#2.dp[i] = dp[i-1] + dp[i-dp[i-1]-2] if s[i]=')' and s[i-1]=')' and dp[i-dp[i-1]-1]='('
#note:第二个方程判断的是在dp[i-1]有效串前字符是(,则成为一给有效括号对。
if s == "":return 0
dp = [0] * len(s)
for i in range(1,len(s)):
if s[i] == ')':
if s[i-1] == '(':
dp[i] = dp[i-2]+2 if i-2>=0 else 2
else:
if i-dp[i-1]>0 and s[i-dp[i-1]-1]=='(':
print(dp[i-1], dp[i-dp[i-1]-2])
dp[i] = dp[i-1]+(dp[i-dp[i-1]-2] if i-dp[i-1]-2>=0 else 0)+2
res = max(dp)
return res
class Solution:
def longestValidParentheses(self, s: str) -> int:
# if s == "":return 0
stack = [-1]
res = 0
for i in range(len(s)):
if s[i] == "(":
stack.append(i)
else:
stack.pop()
if stack==[]:
stack.append(i) #如果栈空,说明当前状态下右括号数目大于左括号了,从头开始计算子串。
else:
res = max(res, i-stack[-1])
return res