最长有效括号
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-valid-parentheses
分析
动态规划
dp[i]代表到i的最长的有效括号,这里的定义一定是包含第i个字符的(动态规划最难的果然是状态定义)
对dp[i]的更新有三种情况
- 如果s[i]==’(’ ,根据上面的定义,要包括第i个,所以肯定凑不成合法的字符串,dp[i]=0(初始化就为0)
- s[i]==’)’,那么我们的s[i-1]如果能和它配成一对,那么就是前面的一组加了后面的(),所以dp[i]=dp[i-2]+2 //-> s[i-2] ‘(’ ‘)’
- s[i]==’)’,如果s[i-1]是’)’,不能凑成一对,那么怎么处理呢,这就是难点,首先看dp[i-1]这部分,这部分已经计算过了就是dp[i-1]个合法的,那第i-1( ‘)’ )个字符就在这里面,那么第i个字符和谁匹配呢,那就是和这些dp[i-1]匹配完了前面的一个索引是 i-dp[i-1]-1匹配,如果是’(’,完美,匹配成功,还要加上索引前面的一片匹配成功的,就是dp[i-dp[i-1]-2];如果是’)’,匹配失败,一败涂地,就直接挂0.
一开始我还想使用二维数组区间dp,感觉像最长未匹配括号 这个的D,还是答案更清楚!
代码
class Solution {
public:
int longestValidParentheses(string s) {
int len=s.length(),m=0;
vector<int> dp(len,0);
for(int i=1;i<len;i++)
{
if(s[i]==')'){
int tmp=i-dp[i-1]-1;
if(i>=2&&s[i-1]=='(')
dp[i]=dp[i-2]+2;
else if(tmp>=0&&s[tmp]=='('){
dp[i]=dp[i-1]+2;
if(tmp>=1)
dp[i]+=dp[tmp-1];
}
}
m=max(dp[i],m);
}
return m;
}
};