题目描述
给定一个只包含 '('
和 ')'
的字符串,找出最长的包含有效括号的子串的长度。
示例
输入: "(()"
输出:2
解释: 最长有效括号子串为 "()"
输入: ")()())"
输出:4
解释: 最长有效括号子串为 "()()"
题目理解
要求通过输入的括号串,找到其中最长的有效子串,即每个括号都有对应的匹配项。
这里要注意,是要找出连续的子串。
解题思路
对于括号匹配,最初想到的就是借助栈来完成匹配操作。
这里由于我们需要得到有效的子串长度,所以我们必须在栈中记录下每个括号的下标。当出现不满足条件的情况时,计从而算当前有效子串长度。
在这里我们需要在栈底加入一个-1
用于做一个偏移(由于下标从0开始,长度需要加一),默认将其视为(
。
对于每个字符,我们都进行如下判断:
- 如果字符为
(
,我们则压栈。 - 如果为
)
,我们将弹出一个匹配,这时会有两种情况- 如果栈为空,则说明当前字符前的所有字符串都已完全匹配成功,但是由于我们在一开始加入了一个偏移,而这个位置默认是为
(
的,所以我们可以知道,这个)
实际上是无效的匹配项。我们直接将这个位置的下标值作为新的偏移值压入栈中。 - 如果栈不为空,则说明栈顶与当前位置之间的子串正好为一个有效的子串,需要和当前最大长度进行对比,判断是否需要覆盖当前最大长度。
- 如果栈为空,则说明当前字符前的所有字符串都已完全匹配成功,但是由于我们在一开始加入了一个偏移,而这个位置默认是为
这里我们可以注意到,不能匹配到的(
将永远在栈中,以偏移的形式存在。
对应代码如下:
class Solution {
public:
int longestValidParentheses(string s) {
if(s.size()<2)
return 0;
int stack[s.size()+1];
int top = 0;
int maxlength = 0;
//哨兵
stack[top++] = -1;
for(int i = 0;i<s.size();i++){
if(s[i] == '('){
stack[top++] = i;
}else{
top--;
if(top == 0){
stack[top++] = i;
}else{
maxlength = maxlength>i-stack[top-1]?maxlength:(i-stack[top-1]);
}
}
}
return maxlength;
}
};
运行结果如下:
我的所有解题代码都会上传到我的github上,需要可以自取。