问题描述
给定一个只包含'('
和')'
的字符串,找出最长的包含有效括号的字串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
解题报告
- 动态规划
d p [ i ] dp[i] dp[i] 表示以 第i
个字符结尾的最长有效字符串的长度。我们只需考虑‘)’所在的字符。
当前一个字符为'('
,则 d p [ i ] = d p [ i − 2 ] + 2 dp[i]=dp[i-2]+2 dp[i]=dp[i−2]+2;
当前一个字符为')'
,则 d p [ i ] = d p [ i − 1 ] + d p [ i − 1 − d p [ i − 1 ] + 1 − 1 − 1 ] + 2 i f d p [ i − 1 − d p [ i − 1 ] + 1 − 1 ] = = ′ ( ′ dp[i]=dp[i-1]+dp[i-1-dp[i-1]+1-1-1]+2\;\;\;if\;dp[i-1-dp[i-1]+1-1]=='(' dp[i]=dp[i−1]+dp[i−1−dp[i−1]+1−1−1]+2ifdp[i−1−dp[i−1]+1−1]==′(′ - 栈
当遇见'('
时,将其 下标 压入栈中;
当遇见')'
时,弹出栈顶元素,然后将当前元素和新的栈顶做差,得到当前有效括号字符串的长度。;
初始化将 -1 压入栈中【必须是 -1】。
实现代码
- 动态规划
class Solution {
public:
int longestValidParentheses(string s) {
int n=s.size(),ans=0;
vector<int>dp(n);
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]>0&& s[i-dp[i-1]-1] == '('){
dp[i]=dp[i-1]+(i>=2+dp[i-1]?dp[i-2-dp[i-1]]:0)+2;
}
ans=max(ans,dp[i]);
}
}
return ans;
}
};
- 栈
class Solution {
public:
int longestValidParentheses(string s) {
stack<int>st;
st.push(-1);
int size=s.size(),ans=0;
for(int i=0;i<size;i++){
if(s[i]=='(')
st.push(i);
else{
st.pop();
if(st.empty())
st.push(i);
else
ans=max(ans,i-st.top());
}
}
return ans;
}
};
参考资料
[1] Leetcode 32. 最长有效括号
[2] 题解区官方答案