代码重构:leetcode 32. 最长有效括号

159 阅读1分钟

32. 最长有效括号

是一个dp的题目,设dp[i]表示以i结尾的最长匹配串的长度。接着我们就可以考虑两种情况:

  1. s.charAt(i)=='(' 这种情况显然dp[i]=0
  2. s.charAt(i)==')' 为不失一般性,设当前串为((...)(...)
    1. 具体分析下,就可以得到此时要匹配的左括号应该位于一连串已经匹配的串之前,显然这个字符的位置是i-1-dp[i-1]
    2. 于是就可以得到dp[i]=dp[i-1]+2+dp[i-1-dp[i-1]-1]
  3. 但我们要注意初始化情况,包括越界考虑的问题。我们主要的假设是判定两段连续都存在,于是我们需要在写的时候解决是否两段都存在的问题。

下面给出两种处理,一种是利用判断,以及扩充dp数组来求解,第二种是利用逻辑表达式来简化处理。

第一种:

    public int longestValidParentheses(String s) {
        if (s == null || s.length() <= 1) return 0;
        int[] dp = new int[s.length() + 1];
        int ans = 0;
        for (int i = 1; i < s.length(); i++) {
            if (s.charAt(i) == ')') {
                if (i - dp[i] - 1 >= 0 && s.charAt(i - dp[i] - 1) == '(') dp[i + 1] = dp[i] + 2 + dp[i - dp[i] - 1];
            }
            ans = Math.max(ans, dp[i + 1]);
        }
        return ans;
    }

第二种:比较推荐这一种,因为当逻辑和建模相等时候,会比较好写以及方便debug,逻辑表达式蛮有用的。

    public int longestValidParentheses(String s) {
        if (s == null || s.length() <= 1) return 0;
        int[] dp = new int[s.length()];
        int ans = 0;
        for (int i = 1; i < s.length(); i++) {
            if (s.charAt(i) == ')') {
                if (i - 1 - dp[i - 1] >= 0 && s.charAt(i - 1 - dp[i - 1]) == '(')
                    dp[i] = dp[i-1] + 2 + ((i - 2 - dp[i - 1]) >= 0 ? dp[i - 2 - dp[i - 1]] : 0);
            }

            ans = Math.max(ans, dp[i]);
        }
        return ans;
    }