最长有效括号
题目描述:
给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = "(()" 输出:2 解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())" 输出:4 解释:最长有效括号子串是 "()()"
示例 3:
输入:s = "" 输出:0
提示:
0 <= s.length <= 3 * 104
s[i]
为'('
或')'
思路分析:
提到括号处理很自然的想到栈,毕竟栈在处理字符匹配上有着天然的优势
遍历整个字符串s,把所有的合法括号序列按照括号来分类,。左括号入栈,右括号出栈。对于每一个右括号,都去求一下以这个右括号为右端点的最长的合法括号序列的长度。我们把每个右括号都枚举一遍之后,再取一个max,就是整个的最大长度。
具体实现:
1、用栈维护当前待匹配的左括号的位置,同时用 start 记录一个新的可能合法的子串的起始位置,初始设为0。
2、如果s[i] =='(',那么把i进栈。
3、如果s[i] == ')',那么弹出栈顶元素 (代表栈顶的左括号匹配到了右括号),出栈后:
如果为空,说明当前的序列合法,并用ant记录此时的序列长度
如果栈不为空,则减去还在栈中的未匹配符号,用ant记录此时的序列长度
4、遇到右括号)且当前栈为空,则当前的 start 开始的子串不可能为合法子串了,更新 start = i + 1。
代码实现注解:
class Solution {
public int longestValidParentheses(String s) {
Stack<Integer> stack = new Stack<>();
//start用于记录有效字符的起始位置
int ans =0,start =0;
for(int i = 0;i<s.length();i++){
//如果是‘(’则压入栈中
if(s.charAt(i) == '(')
stack.add(i);
//如果是‘)’
else
{
//如果栈不为空
if(!stack.isEmpty()){
//将左括号出栈
stack.pop();
//再次判断出栈后栈是否为空
if(stack.isEmpty())
//如果为空,说明当前的序列合法,并用ant记录此时的序列长度
ans = Math.max(ans,i-start+1);
else
//如果栈不为空,则减去还在栈中的未匹配符号,用ant记录此时的序列长度
ans = Math.max(ans, i-stack.peek());
}
//遇到右括号)且当前栈为空,则当前的 start 开始的子串不可能为合法子串了,更新 start
else
start =i+1;
}
}
return ans;
}
}