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.
这个题最开始思路有点混乱,试了几遍总是没有考虑清楚所有情况。后来推倒重来,把思路重新理清了再做,就很容易过了。
这说明编程之前必须要考虑清楚,如果没有想清楚就动手,后来发现各种漏洞,再在烂程序的基础上打补丁,消耗太大了。
class Solution {
public:
//使用了一个栈q来记录历史。q中的数有两种。
//负数表示历史,即绝对值当前位置的左边存了多少长度的括号。(这样的设计并不直观,不是好的编程习惯,但这里先这样设计)
//非负的数表示s的索引,指示栈顶的括号是左括号还是右括号。如果当前括号为左括号,则将其直接压栈。
//如果当前括号为右括号,则先将其左边有多少长度的历史弹出并累加,直到栈顶有一个左括号或右括号。
//如果栈顶为右括号,则之前的历史作废。因为栈里出现的右括号说明其左边已无法匹配
//如果栈顶为左括号,则将左括号弹出,将累加的历史再+2,再继续累加栈顶的历史,直到栈空或栈顶为括号,将累加的历史求负压栈。
//这个过程中将最后累加的历史与最大值比较,遍历整个字串后输出最大值即可
int longestValidParentheses(string s) {
int n = s.size();
if(n<=1){
return 0;
}
int max_len=0;
stack<int> q;
for(int i=0;i<n;++i){
if(s[i]=='('){
q.push(i);
}
else if(s[i]==')'){
int curr = 0;
while(!q.empty() && q.top()<0){//弹出并累加最右边的历史长度
curr -= q.top();
q.pop();
}
if(!q.empty() && s[q.top()]=='('){//若栈顶为左括号
int qtop = q.top();
curr += 2;//长度增加2
q.pop();
while(!q.empty() && q.top()<0){//再累加左括号左边的历史
curr -= q.top();
q.pop();
}
if(curr>max_len){
max_len = curr;//与最大值比较
}
q.push(-curr);//缓存当前最右匹配长度
}
else{
q.push(i);//已到左边界或出现右括号,左边已无法连上,压入一个右括号以隔断
}
}
else{;}//error
}
return max_len;
}
};