LeetCode—32. Longest Valid Parentheses
题目
https://leetcode.com/problems/longest-valid-parentheses/description/
找出最长的合法括号组合子串。
思路及解法
这道题是20. Valid Parentheses的进阶。20题是用栈存储字符来完成的。这道题也会用的到栈,但是如果存储字符是不能完成任务的。
一个非常巧妙的方法是栈来存储字符的index。栈中存储的是不能得到匹配的括号,不论是左还是右。只要有匹配成功的小可爱,我们就让他出栈,跟他的小伙伴玩去。实际上,不论是“()”和“(())”还是“()()”,本质上出栈的情况只有这一种:“()”。我们可以这样计算长度,匹配成功后,用当前字符的i减去当前位于栈顶元素的index,就是当前匹配成功的字符串的长度。
然后我们来说明一下步骤:
1.如果是左括号,直接push
2.如果是右括号,说明是可能存在匹配成功的机会的,这时候我们去看一下栈顶的元素
2.1注意如果栈顶元素不存在,我们push这个右括号
2.2如果栈顶元素是右括号,我们还是push这个右括号
2.3如果栈顶元素是左括号,我们pop出左括号这个小可爱,让他和小伙伴玩去,我们处理后面的事
2.3.1pop出左括号后如果栈不为空,那么当前匹配到的子串长度就是这个右括号的下标i减去栈顶元素index
2.3.2如果这时候栈为空了,说明i前面的子串都匹配成功了,所以长度就是i+1
思路是很清晰的,不过代码写起来有点繁杂,不过能帮助理解。如果有想看简洁代码的同学可以看这篇。
另外,这道题还可以用动态规划来做,等我回来补充。。。
代码
class Solution {
public int longestValidParentheses(String s) {
int len = s.length();
if(len==0 || len==1) return 0;
int max = 0;
Stack<Integer> stack = new Stack<>();
for(int i=0; i<len; i++){
if(s.charAt(i)=='(' ){
stack.push(i);
}else{
if(!stack.isEmpty()){
if(s.charAt(stack.peek())=='('){
stack.pop();
if(!stack.isEmpty()){
max = Math.max(max, i-stack.peek());
}else{
max = i+1;
}
}else{
stack.push(i);
}
}else{
stack.push(i);
}
}
}
return max;
}
}