每日一题 为了工作 2020 0501 第六十题

Posted walxt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题 为了工作 2020 0501 第六十题相关的知识,希望对你有一定的参考价值。

/**
 *
 * 问题:括号字符串的最长有效长度
 *       给定一个括号字符串返回最长的有效字符串子串
 *
 * 分析:
 * 用动态规划求解,可以做到时间复杂度为O(N), 额外空间复杂度为O(N)。
 * 首先生成长度和str字符串一样的数组dp[],dp[i]值的含义为str[O .. i]中必须以字符str[i]结
 * 尾的最长的有效括号子串长度。那么dp[i]值可以按如下方式求解:
 * 1. dp[O]=O。只含有一个字符肯定不是有效括号字符串, 长度自然是0。
 * 2. 从左到右依次遍历str[I .. N-1]的每个字符, 假设遍历到str[i].
 * 3. 如果str[i]="(", 有效括号字符串必然是以")"结尾, 而不是以"("结尾,所以dp[i]= 0。
 * 4. 如果str[i]=")", 那么以str[i]结尾的最长有效括号子串可能存在。dp[i-1]的值代表必
 *    须以str[i-1]结尾的最长有效括号子串的长度,所以如果i-dp[i-1]-1位置上的字符是"(",
 *    就能与当前位置的str[i]字符再配出一对有效括号。比如"(()())", 假设遍历到最后一个
 *    字符")",必须以倒数第二个字符结尾的最长有效括号子串是"()()",找到这个子串之前的字
 *    符,即i-dp[i-1]-1位置的字符,发现是"(" ,所以它可以和最后一个字符再配出一对有效括
 *    号。如果该情况发生, dp[i]的值起码是dp[i-1]+2, 但还有一部分长度容易被人忽略。比
 *    如"()(())",假设遍历到最后一个字符")",通过上面的过程找到的必须以最后字符结尾的最
 *    长有效括号子串起码是"(())",但是前面还有一段"()"可以和"(())"结合在一起构成更大的
 *    有效括号子串。也就是说,str[i-dp[i-1]- 2]和str[i]配成了一对,这时还应该把
 *    dp[i-dp[i-1]-2]的值加到dp[i]中,这么做表示把str[i-dp[i-1]-2]结尾的最长有效括号子
 *    串接到前面, 才能得到以当前字符结尾的最长有效括号子串。
 * 5. dp[ .. N-1]中的最大值就是最终的结果。
 *
 * @author 雪瞳
 * @Slogan 时钟尚且前行,人怎能再此止步!
 * @Function
 *
 */
public class MaxLength { 
    public static int maxLength(String string){
        if (string == null || "".equals(string)){
            return 0;
        }
        char[] chars = string.toCharArray();
        int[] dp = new int[chars.length];
        int pre = 0;
        int res = 0;
        for (int i=1;i<chars.length;i++){
            if (")".equals(chars[i])){
                pre = i - dp[i-1] -1;
                if (pre >=0 && "(".equals(chars[pre])){
                    dp[i] = dp[i-1]+2+(pre>0?dp[pre-1]:0);
                }
            }
            res = Math.max(res,dp[i]);
        }
        return res;
    }
}

  

以上是关于每日一题 为了工作 2020 0501 第六十题的主要内容,如果未能解决你的问题,请参考以下文章

每日一题 为了工作 2020 0510 第六十八题

每日一题 为了工作 2020 0510 第六十八题

每日一题 为了工作 2020 0508 第六十六题

每日一题 为了工作 2020 0508 第六十六题

每日一题 为了工作 2020 056 第六十四题

每日一题 为了工作 2020 056 第六十四题