Leetcode 1143 最长公共子序列

 

  当一个问题用递推不好描述时,将目光从整体放到局部,用递归描述对于每个元素我们需要做什么。

  问题:text 从 point1 、text2 从 point2 开始的最长公共子序列为 n ,具有递归结构,并存在大量重复子问题。

  分治:

    public final int longestCommonSubsequence(String text1, String text2) {
        return longestCommonSubsequence(text1, 0, text2, 0, new int[text1.length()][text2.length()]);
    }

    public final int longestCommonSubsequence(String text1, int point1, String text2, int point2, int[][] cache) {
        if ((point1 == text1.length()) || (point2 == text2.length())) {
            return 0;
        }
        if (cache[point1][point2] != 0) {
            return cache[point1][point2];
        }
        int re = 0;
        if (text1.charAt(point1) == text2.charAt(point2)) {
            re = longestCommonSubsequence(text1, point1 + 1, text2, point2 + 1, cache) + 1;
        } else {
            int re0 = longestCommonSubsequence(text1, point1, text2, point2 + 1, cache);
            int re1 = longestCommonSubsequence(text1, point1 + 1, text2, point2 + 1, cache);
            int re2 = longestCommonSubsequence(text1, point1 + 1, text2, point2, cache);
            re = Math.max(re0, re1);
            re = Math.max(re, re2);
        }
        cache[point1][point2] = re;
        return re;
    }

  DP:

    public final int longestCommonSubsequenceDP(String text1, String text2) {
        int length1 = text1.length();
        int length2 = text2.length();
        int[][] dp = new int[length1][length2];
        if (length1 == 0 || length2 == 0) {
            return 0;
        }
        dp[length1 - 1][length2 - 1] = text1.charAt(length1 - 1) == text2.charAt(length2 - 1) ? 1 : 0;
        for (int i = length2 - 2; i >= 0; i--) {
            dp[length1 - 1][i] = text1.charAt(length1 - 1) == text2.charAt(i) || dp[length1 - 1][i + 1] == 1 ? 1 : 0;
        }
        for (int i = length1 - 2; i >= 0; i--) {
            dp[i][length2 - 1] = text1.charAt(i) == text2.charAt(length2 - 1) || dp[i + 1][length2 - 1] == 1 ? 1 : 0;
        }
        for (int i = length1 - 2; i >= 0; i--) {
            for (int j = length2 - 2; j >= 0; j--) {
                if (text1.charAt(i) == text2.charAt(j)) {
                    dp[i][j] = dp[i + 1][j + 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i][j + 1], dp[i + 1][j + 1]);
                    dp[i][j] = Math.max(dp[i][j], dp[i + 1][j]);
                }
            }
        }
        return dp[0][0];
    }

原文地址:https://www.cnblogs.com/niuyourou/p/13282217.html