这道题目也是相当经典的一道题目了
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
代码一最能想到的方法,用栈实现
class Solution {
public static int longestValidParentheses(String s) {
if (s.length() < 2) {
return 0;
}
Stack<Integer> stack = new Stack<>();
//插入-1的目的例如()()()这种情况
stack.add(-1);
int length = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.add(i);
} else {
stack.pop();
if(!stack.isEmpty()) {
length = Math.max(length, i - stack.peek());
}else{
//如果为空我们需要更改标志位,例如())()
//当i等于2时出现不匹配也就是()),那么后面我们在进行判断时就要以i=2为基准,因为i后面的括号已经不可能再和i前的括号匹配了;但如果是()()()()这种情况,基准就一直是-1,因为前面的括号可以一直和后面匹配
stack.add(i);
}
}
}
return length;
}
}
代码二比较巧妙,两次遍历即可
class Solution {
public static int longestValidParentheses(String s) {
int left=0;
int right=0;
int length=0;
//第一个循环从左往右判断类似于这样的用例:()()()))),因为我们只有在left==right,才会进行比较。
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='('){
left++;
}else{
right++;
}
if(right>left){left=0;right=0;}
if(right==left){length=Math.max(length,2*left);}
}
left=0;
right=0;
//第二个循环从右往左判断可能出现的这种情况:(((((()()。
for(int i=s.length()-1;i>=0;i--){
if(s.charAt(i)=='('){
left++;
}else{
right++;
}
if(right<left){left=0;right=0;}
if(right==left){length=Math.max(length,2*left);}
}
return length;
}
}