Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
For “(()”, the longest valid parentheses substring is “()”, which has length = 2.
Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.
方法一:堆栈法。
建一个栈存放索引,先放入-1,然后遇到左括号就压入,右括号就看栈顶是否是左括号,如果是就弹出,然后计算当前索引和栈顶索引的差值,更新最大值。
注意栈顶是-1的时候是空栈,不管是什么括号都是直接放。
class Solution {
public:
int longestValidParentheses(string s) {
stack<int>stk;
stk.push(-1);
int res=0;
for(int i=0;i<s.size();i++){
int t=stk.top();
if(t!=-1&&s[i]==')'&&s[t]=='('){
stk.pop();
res=max(res,i-stk.top());
}
else{
stk.push(i);
}
}
return res;
}
};
方法二:动态规划法。
这个题也可以考虑动态规划的思想,s[i]表示字符串s的第i个字符,dp[i]表示以i为结束索引时有效括号的长度,只需一次遍历所有索引的情况,找到最大值即可。
动态方程:
s[i]=‘)’且s[i-1]=‘(’时,dp[i]=dp[i-2]+2
s[i]=‘)’且s[i-1]=‘)’时,如果s[i-dp[i-1]-1]=‘(’,那么
dp[i]=dp[i-1]+dp[i-dp[i-1]-2]+2;
其实可以统一为第二个公式,因为s[i-1]=’(‘时,dp[i-1]=0.
class Solution {
public:
int longestValidParentheses(string s) {
if(s.empty()) return 0;
int res=0,n=s.size();
vector<int>f(n,0);
for(int i=1;i<n;i++){
if(s[i]==')'){
if(i-f[i-1]-1>=0&&s[i-f[i-1]-1]=='('){
f[i]=f[i-1]+2+((i-f[i-1]-2>=0)?f[i-f[i-1]-2]:0);
res=max(res,f[i]);
}
}
}
return res;
}
};