LeetCode0032-最长有效括号

字节二面算法题。

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

 https://leetcode-cn.com/problems/longest-valid-parentheses/comments/

 

以下实现的是,找出有效的括号对数(输出有效括号的数目),没有实现连续

 //dp[i]表示第i位上有效括号的长度
    public int longestValidParentheses(String s) {
        if(s==null||s.length()<=0) return 0;

        int[] dp = new int[s.length()];
        dp[0]=0;
        int max=0;

        int i=1;
        while(i<s.length()){
            char ch= s.charAt(i);
            if(ch =='('){
                dp[i] = dp[i-1];
            }else{
                if(s.charAt(i-1)=='('){
                    dp[i]=dp[i-1]+2;
                }else if(s.charAt(i-1) == ')'){
                    if(i-dp[i-1]-1<0){
                        dp[i]=dp[i-1];
                    }
                    else if(s.charAt(i-dp[i-1]-1)=='('){
                        dp[i]=dp[i-1]+2;
                    }else{
                        dp[i]=dp[i-1];
                    }
                }
            }
            max=Math.max(dp[i],max);
            i++;
        }
        return max;
    
    }

 以下为最后结果:

重点:

理清公式:

dp[i]记录的是,以string.charAt(i)位置为结尾的,有效连续括号的长度,重点要看当前位置对于整个括号的贡献。对于"()(",dp[0]=0;dp[1]=2;dp[3]=0,因为在位置3上,“()(”根本不是一个有效括号!所以dp[3]=0

 

公式:

当 s[i] = '(' 时,s[i] = 0;

当s[i] = ') '时,如果 s[i-1]='(',则 dp[i] = dp[i-2]+2;  (保证i-2>=0)

           如果s[i-1]=')',若,i-dp[i-1]-1='(',则 dp[i] = dp[i-1] +2 + dp[i-dp[i-1]-2]   (保证i-dp[i-1]-2>=0); 若  i-dp[i-1]-1不是'('或者为空,则 dpp[i]=0,表示当前位置的')'无法构成一个有效的括号。

                      上面公式是指:在dp[i-1]个有效括号之前(i-dp[i-1]-1),是否有一个'('可以与当前位置的右括号构成一个有效的括号,此外也需要考虑,在这个左括号之前是否已经有连续的括号(dp[i-dp[i-1]-2]的值); 

 

 

class Solution {
    //dp[i]表示第i位上有效括号的长度
    public static int longestValidParentheses(String s) {
        if(s==null||s.length()<=0) return 0;

        int[] dp = new int[s.length()];
        dp[0]=0;
        int max=0;

        int i=1;
        while(i<s.length()){
            char ch= s.charAt(i);
            if(ch =='('){
                dp[i] = 0;
            // ch == ')'时
            }else{
                //如果恰好左边为左括号,则+2,需要控制i-2>=0
                if(s.charAt(i-1)=='('){
                    dp[i]= (i>=2?dp[i-2]+2:2);
                }
                //如果左边为右括号,需要判断跨过前面有效括号dp[i-1]的前一个是什么括号
                else {
                    // if(i-dp[i-1]-1<0){
                    //     dp[i]=0;
                    // }
                    // else if(s.charAt(i-dp[i-1]-1)=='('){
                    //     dp[i]=dp[i-1]+2+(i-dp[i-1]-2>=0?dp[i-dp[i-1]-2]:0);
                    // }else{
                    //     dp[i]=0;
                    // }
                    if(i-dp[i-1]-1>=0 && s.charAt(i-dp[i-1]-1)=='('){
                        dp[i]=dp[i-1]+2+(i-dp[i-1]-2>=0?dp[i-dp[i-1]-2]:0);
                    }else{
                        dp[i]=0;
                    }
                }
            }
            max=Math.max(dp[i],max);
            i++;
        }
        return max;
    
    }


 public static void main(String[] args) {

        String s =")()())()()(";
        int result =longestValidParentheses(s);
        System.out.println(result);

    }
}

 

posted on 2021-07-15 20:25  cStream  阅读(43)  评论(0)    收藏  举报