题目
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.
题目分析
首先要先明确哪个括号是和哪个括号匹配的,如果括号匹配类型的题目做得多的话我们知道遇上括号匹配的问题通常都是建立一个栈,然后把括号放入,当要放入‘)’遇上栈顶的‘(’的时候就表示出现了一个括号匹配并把栈顶的‘(’弹出,也就是说,‘)’永远是和离它最近的没和其他‘)’匹配的‘(’匹配的。对于这道题,要得到一个所有括号都匹配的子串也就是子串里的括号都得到了匹配,而子串两端的两个括号都是没有匹配的,也就是说,即使子串右端是‘(’,这个也是没有匹配的,否则他也归入这个子串了,这也代表没有匹配的括号中间是子串。如果这样想的话,那么这题就很简单了,我们只要先对总串中的每一个括号都判断他是否匹配的,对于不能匹配的括号存下他们的下标,在这些括号中间的就是能符合条件的子串,只要从中找出最长的即可。
想到括号匹配自然用栈来完成,只不过这里的栈存的是括号的下标,从串的开头扫一遍串,每遇到一个括号就进行如下操作:
如果栈原来为空就把这个括号的下标放入栈看下一个括号,如果不空,那么有两种情况:
1.遇到的是‘(’,那么这种就把下标放入栈去看下一个括号
2.遇到的是‘)’,那么这种看栈顶下标对应的元素是不是‘(’,如果是的话则把栈顶元素弹出去看下一个括号,如果不是则把这个括号放入(这个括号不会再有机会弹出栈,表示他是个没有匹配的括号)
当总串扫描完后,我们只要把栈顶元素逐个pop出来,相邻两个元素的差值就是子串的长度,记录下其中最长的即可
c++代码
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> invalid_index;
for (int i = 0; i < s.length(); i++) {
if (invalid_index.size() == 0) {
invalid_index.push(i);
continue;
}
else {
if (s[invalid_index.top()] == '(') {
if (s[i] == ')') invalid_index.pop();
else invalid_index.push(i);
}
else {
invalid_index.push(i);
}
}
}
int max = 0, temp = s.length();
while(!invalid_index.empty()) {
int t = invalid_index.top();
invalid_index.pop();
if (max < temp - t - 1) max = temp - t - 1;
temp = t;
}
if (max < temp) max = temp;
return max;
}
};