一、题目
给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
输入:s = “)()())”
输出:4
解释:最长有效括号子串是 “()()”
二、解法
思路:动态规划
d
p
[
i
]
dp[i]
dp[i]表示以
s
[
i
]
s[i]
s[i]结尾的有效子串的最长长度。考察
s
[
i
]
s[i]
s[i]和
s
[
i
−
1
]
s[i-1]
s[i−1]:
- 若 s [ i ] = = ( s[i]==( s[i]==(,则 d p [ i ] = 0 dp[i]=0 dp[i]=0
- 若
s
[
i
]
=
=
)
s[i]==)
s[i]==),则考察前一位:
- 若 s [ i − 1 ] = = ( s[i-1]==( s[i−1]==(:则 d p [ i ] = d p [ i − 2 ] + 2 dp[i]=dp[i-2]+2 dp[i]=dp[i−2]+2
- 若
s
[
i
−
1
]
=
=
)
s[i-1]==)
s[i−1]==),则要考虑
s
[
i
]
s[i]
s[i]前面有效子串
t
t
t的前一位是否是(
- 如果不是,说明 s [ i ] s[i] s[i]和它不能配对,则 d p [ i ] = 0 dp[i]=0 dp[i]=0
- 如果是,说明可以配对,则 d p [ i ] = d p [ i + 1 ] + 2 + d p [ i − d p [ i − 1 ] − 2 ] dp[i]=dp[i+1]+2+dp[i-dp[i-1]-2] dp[i]=dp[i+1]+2+dp[i−dp[i−1]−2],要特别注意还需要加上 d p [ i − d p [ i − 1 ] − 2 ] dp[i-dp[i-1]-2] dp[i−dp[i−1]−2],比如"()(())",dp依次是020026
class Solution {
public:
int longestValidParentheses(string s) {
int n=s.length();
vector<int> dp(n,0);
int ans=0;
for(int i=1;i<n;++i){
if(s[i]==')'){
if(s[i-1]=='('){
dp[i]=(i>=2?dp[i-2]:0)+2;
}else{
if(i-dp[i-1]-1>=0&&s[i-dp[i-1]-1]=='('){
dp[i]=dp[i-1]+2+(i-dp[i-1]-2>=0?dp[i-dp[i-1]-2]:0);
}
}
ans=max(ans,dp[i]);
}
}
return ans;
}
};