Given a string containing just the characters'('and')', find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is
"()"

Example 2:
Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"
这道题比较典型,题目的关键点在于在一端区域内()数目相等,且任一小段没有)数目大于(的情况。
每次出现(并不能直接增加数目,)每次出现可以直接知道以)为右边的最长数目
第一种通过栈储存层次信息

public int longestValidParentheses(String s) {
    char[] array=s.toCharArray();
    int max=0;
    Stack<Integer> stack=new Stack();
    stack.add(-1);
    for(int i=0;i<array.length;i++){
        char c=array[i];
        if(c=='('){
            stack.push(i);
        }else{
            stack.pop();
            if(stack.isEmpty()){
                stack.push(i);
            }else{
                max=Math.max(max,i-stack.peek());
            }
        }
    }
    return max;
}

还有一种,通过数组来存储信息,就是动态规划

public int longestValidParentheses(String s) {
        char[] array=s.toCharArray();
        int max=0;
        int[] dp=new int[array.length+1];
        for(int i=2;i<=array.length;i++){
            char c1=array[i-1];
            char c0=array[i-2];
            if(c1==')'){
                if(c0=='('){
                    dp[i]=dp[i-2]+2;
                }else{
                    if(i-1-dp[i-1]-1>=0 && array[i-1-dp[i-1]-1]=='('){
                        dp[i]=dp[i-1]+2+dp[i-1-dp[i-1]-1];
                    }
                }
            }
            max=Math.max(max,dp[i]);
        }
        return max;
}

还有一种非常巧妙的解法,只要数目相等,就可以计数

public int longestValidParentheses(String s) {
        char[] array=s.toCharArray();
        int max=0;
        int left=0;
        int right=0;
        for(int i=0;i<array.length;i++){
            char c=array[i];
            if(c=='(') left++;
            else right++;
            if(left==right){
                max=Math.max(max,2*left);
            }else if(right > left){
                left=0;
                right=0;
            }
        }
        left=0;
        right=0;
        for(int i=array.length-1;i>=0;i--){
            char c=array[i];
            if(c=='(') left++;
            else right++;
            if(left==right){
                max=Math.max(max,2*right);
            }else if(left > right){
                left=0;
                right=0;
            }
        }
        return max;
}

上面的上发在于解决了没有彻底包围时就已经成为最长的计数问题。


程浩
21 声望2 粉丝