问题
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
思考
这道题标记为难,也的确是有些难度。受到前一道类似问题的思维影响,更不得其要领。最终参考网络上其他人的答案。
仍旧是利用栈的思维进行解答,在处理最长字符串时有些巧妙的点。
但在该题的求解中,动态规划的思维过于复杂,因此这里不再采用该方法。
内容如下:
但是做题的时候,发现了一个难点,即示例2的情况,第二个字符和第三个字符是一对有效的括号,此有效括号子串长度为2,第四个字符和第五个字符也是一对有效的括号,且这两个有效括号子串是挨着的,返回的结果应该是这两个有效括号子串长度之和。
算法的难度在于如何判断两个有效括号子串是否直接相邻,若直接相邻,则最长有效括号子串需要将这两个相邻的子串包含进来,并且左右边界需往外扩展,如上例中,下标2和下标21所处位置的字符其实也是在最长有效括号子串中的。
程序思路
解题思路:
1.需有一个变量start记录有效括号子串的起始下标,max表示最长有效括号子串长度,初始值均为0。
2.遍历给字符串中的所有字符
2.1若当前字符s[index]为左括号’(’,将当前字符下标index入栈(下标稍后有其他用处),处理下一字符。
2.2若当前字符s[index]为右括号’)’,判断当前栈是否为空
2.2.1若栈为空,则start = index + 1,处理下一字符(当前字符右括号下标不入栈)
2.2.2若栈不为空,则出栈(由于仅左括号入栈,则出栈元素对应的字符一定为左括号,可与当前字符右括号配对),判断栈是否为空
2.2.2.1若栈为空,则max = max(max, index-start+1)
2.2.2.2若栈不为空,则max = max(max, index-栈顶元素值)
代码
import java.util.Stack;
public class _32LongestValidParentheses{
//the problem is not easy as i think at first
//"()(()" the second"(" is not so easy to del with
public int longestValidParentheses(String s){
int start = 0;
int maxlength =0;
Stack<Integer> stack = new Stack();
for(int i =0;i< s.length();i++){
if(String.valueOf(s.charAt(i)).equals("(")){
stack.push(i);
continue;
}else{
if(stack.empty()){
start = i+1;
}else{
stack.pop();
if(stack.empty()){
maxlength = Math.max(maxlength,i-start+1);
}else{
maxlength = Math.max(maxlength,i-stack.peek());
}
}
}
}
return maxlength;
}
public static void main(String[] args){
_32LongestValidParentheses LongestValidParentheses = new _32LongestValidParentheses();
String s1 = "(()";
String s2 = ")()())";
String s3 = "()(()";
int len1 = LongestValidParentheses.longestValidParentheses(s1);
int len2 = LongestValidParentheses.longestValidParentheses(s2);
int len3 = LongestValidParentheses.longestValidParentheses(s3);
System.out.println(len1);
System.out.println(len2);
System.out.println(len3);
}
}