给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
方法一
int longestValidParentheses(string s) {
//start记录有效字串开始位置
int res=0,start=0,n=s.size();
stack<int> st;
for(int i=0;i<n;++i){
if(s[i]=='(') {
//st存储入栈左括号的位置
st.push(i);
}
else if(s[i]==')'&&st.size()){
st.pop();
//如果此时栈为空说明栈中的所有左括号已经配对
if(!st.size()){
res=max(res,i-start+1);
}
//有可能栈中的左括号没法全部配对,例如"((())"
else res=max(res,i-st.top());
}
//如果遇到右括号且栈中已无左括号,则重新设置start
else{
start=i+1;
}
}
return res;
}
方法二
使用两个变量left和right,分别表示左右括号数量。从左向右遍历字符串,因为有效字符串左括号数量必定等于右括号数量,当right>left表明当前子串必定无效,此时令left=right=0从当前位置重新计数;当left=right时当前子串有效,更新res。有一个问题是像"(()"这样的没法更新res,解决方法是同样的方法从右往左再遍历一遍。
int longestValidParentheses(string s) {
int res=0,n=s.size(),left=0,right=0;
for(int i=0;i<n;++i){
(s[i]=='(')?left++:right++;
if(right>left) left=right=0;
else if(right==left) res=max(res,right*2);
}
left=0,right=0;
for(int i=n-1;i>=0;--i){
(s[i]=='(')?left++:right++;
if(right<left) left=right=0;
else if(right==left) res=max(res,left*2);
}
return res;
}
leetcode原题链接:https://leetcode-cn.com/problems/longest-valid-parentheses