思路一:
1.和判断括号是否匹配相似,先遍历一回字符串,能匹配的先弹栈,不能匹配的先将下标压栈。
此时,需要注意一个特殊情况:当字符串为空时,可直接返回0.
2.再遍历一回栈,根据留在栈中的下标判断每一串匹配好的括号的长度,选择最长的一个即可。
在此过程中,需要注意以下几个特殊情况:
(1)栈为空:说明整个串均为有效的括号
(2)栈底元素不为1:说明在串的开头存在有效括号,不要漏了
(3)栈顶元素不为n-1(n为串的长度):说明在串的结尾处存在有效括号,不要漏了
class Solution {
public:
int longestValidParentheses(string s) {
vector<int> parentheses_stack;
int ans=0,i,n=s.size();
if(n==0 || n==1)
return 0;
for(i=0;i<n;i++)
{
if(s[i]=='(')
parentheses_stack.push_back(i);
else
{
if(parentheses_stack.empty())
parentheses_stack.push_back(i);
else if(s[*(parentheses_stack.end()-1)]=='(')
parentheses_stack.pop_back();
else
parentheses_stack.push_back(i);
}
}
n=parentheses_stack.size();
if(n==0)
return s.size();
if(parentheses_stack[0]!=0)
ans=parentheses_stack[0];
for(i=0;i<n-1;i++)
if(ans<(parentheses_stack[i+1]-parentheses_stack[i]-1))
ans=parentheses_stack[i+1]-parentheses_stack[i]-1;
if(ans<s.size()-parentheses_stack[n-1]-1)
ans=s.size()-parentheses_stack[n-1]-1;
return ans;
}
};
二、做法同上类似,但不需要遍历两遍,实现起来更简洁
class Solution {
public:
int longestValidParentheses(string s) {
int ans=0,lastError=-1;
vector<int> stack;
for(int i=0;i<s.size();i++)
{
if(s[i]=='(')
stack.push_back(i);
else
{
if(stack.size()>0)
{
stack.pop_back();
int len;
if(stack.size()==0)
len=i-lastError;
else
len=i-stack.back();
if(len>ans)
ans=len;
}
else
lastError=i;
}
}
return ans;
}
};