题意
给一个只包含 '(' 和 ')' 的字符串,求最长有效括号子序列的长度。
如 "(()" 的最长有效括号子序列的长度为2。
思路
动态规划。 dp[i] 表示从下标 i 开始向左数,有效括号子序列的长度。
1° 若 s[i] == '(' ,则 dp[i] = 0
2° 若 s[i] == ')' ,上一个可能与 s[i] 匹配的位置 j = i-1-dp[i-1]
2.1° 若 s[j] == ')' ,不能匹配,dp[i] = 0
2.2° 若 s[j] == '(' ,表示可以匹配,dp[i] = dp[i-1] + 2。若 s[j-1] == ')',表示起始处为 i 的这一段与起始处为 j-1 的这一段可以合并起来(如果根本没有从 j-1 开始的那一段, dp[j-1] == 0,也是没问题的),dp[i] += dp[j-1]
最后找出数组 dp 中的最大元素即可。
C++代码
class Solution {
public:
int longestValidParentheses(string s) {
if(s.size()<2)
return 0;
int n=s.size();
vector<int> dp(n+10,0);
int ans=0;
for(int i=1;i<n;i++)
{
if(s[i]=='(')
continue;
int last=i-1-dp[i-1];
if(last>=0 && s[last]=='(')
{
dp[i]=dp[i-1]+2;
if(last>=1 && s[last-1]==')')
dp[i]+=dp[last-1];
}
ans=max(ans,dp[i]);
}
return ans;
}
};
python代码
class Solution:
def longestValidParentheses(self, s):
"""
:type s: str
:rtype: int
"""
n = len(s)
if n < 2:
return 0
ans = 0
dp = [0] * (n+10)
for i in range(0, n):
if s[i] == '(':
continue
last = i - 1 - dp[i-1]
if last >= 0 and s[last] == '(':
dp[i] = dp[i-1] + 2
if last >= 1 and s[last-1] == ')':
dp[i] += dp[last-1]
ans = max(ans, dp[i])
return ans