题解
思路
代码
class Solution:
### 1228 动态规划(44 ms,14.9 MB)
def longestValidParentheses(self, s: str) -> int:
# 字符串为空,直接返回0
if not s: return 0
n = len(s)
dp = [0] * n # 初始化dp全为0
# 从第二个字符开始遍历(因为无论第一个字符是什么,dp[0]必为0)
for i in range(1, n):
# 若第i个字符为),则分类讨论
if s[i] == ')':
# 若第i个字符为),且第i-1个字符为(,则有效长度直接加2(此时并非是子串情况)
if s[i-1] == '(': dp[i] = dp[i-2] + 2
# 若第i个字符为),且第i-1个字符为)
# 则继续判断第i - dp[i-1] - 1个字符是否存在(越界)?若存在是否为(?
# 若是则找到一个包含有效子串dp[i-1]的更长的字符串dp[i-1] + 2 + dp[i - dp[i-1] - 2]
# 其中dp[i - dp[i-1] - 2]表示第i - dp[i-1] - 1个字符之前是否存在有效字符串
elif (i - dp[i-1]) > 0 and s[i - dp[i-1] - 1] == '(':
dp[i] = dp[i-1] + 2 + dp[i - dp[i-1] - 2]
return max(dp) # 返回dp的最大值
### 1228 栈(48 ms,14.9 MB)
def longestValidParentheses(self, s: str) -> int:
# 字符串为空,直接返回0
if not s: return 0
res = 0
stack = [-1] # 初始化栈,预先存放一个-1用于处理边界情况
# 遍历字符串中的每一个字符
for i in range(len(s)):
# 若第i个字符为(,则入栈
if s[i] == '(': stack.append(i)
else:
# 若第i个字符为),则栈顶元素出栈(表示与新来的)完成匹配)
stack.pop()
# 若栈为空,则将此)入栈表示:最后一个没有被匹配的右括号的下标
if not stack: stack.append(i)
# 计算当前有效长度(当前元素下标 - 栈顶元素下标),并更新最大有效长度
res = max(res, i - stack[-1])
return res