相似的题目Valid Parentheses
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.
对于括号匹配,和Valid Parentheses同样的思路,用栈维护左括号,即在读取字符串的时候,遇到左括号就入栈。遇到右括号就出栈,同时判断当前括号匹配的子串是否为最长子串。
不过在判断括号匹配的子串的长度的时候,有一些值得注意的问题,其中需要借助变量 pos 记录当前括号匹配的子串的左侧位置:
- 如果当前栈为空,这说明当前的右括号并不构成括号匹配的子串,则 pos 移到下一位置;
- 如果当前栈不为空,弹出栈顶元素。
- 此时,如果栈为空,说明加上当前的右括号可以构成括号匹配的子串;其子串长度就为pos位置到当前位置的长度;
- 如果栈不为空,则栈顶元素后面的括号肯定是匹配的,因此子串长度就是栈顶元素位置的后一位置到当前位置的长度;
int longestValidParentheses(string s) {
if (s == "")return 0;
int k = 0;
while (k < s.size() && s[k] == ')')k++;
if (k == s.size())return 0;
stack<int> res;
int cnt = 0, pos = 0;
while (k < s.size()){
if (s[k] == '('){ //遇到左括号,直接存入。
res.push(k);
}
else {
//如果此时栈里左括号已经被消耗完了,没有额外的左括号用来配对当前的右括号了,那么当前的右括号就被单出来了,表明当前子串可以结束了,此时的右括号也成为了下一个group的分界点,此时右括号下标为k,所以下一个group的起始点为k+1,相当于skip掉当前的右括号。
if (res.empty()) pos = k + 1;
else {
//如果此时栈不空,可能有两种情况,1)栈正好剩下1个左括号和当前右括号配对 2)栈剩下不止1个左括号,
res.pop();
//栈pop()之前正好剩下1个左括号,pop()之后,栈空了,此时group长度为k - 1 + pos
if (res.empty())cnt = max(cnt, k - 1 + pos);
//栈有pop()之前剩下不止1个左括号,此时额外多出的左括号使得新的group形成。如()(()())中index=4时,stack中有2个左括号
else cnt = max(cnt, k - res.top());
}
}
k++;
}
return cnt;
}