lintcode77 · 最长公共子序列【中等 动态规划】

题目

https://www.lintcode.com/problem/77

给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。


最长公共子序列的定义:

最长公共子序列问题是在一组序列(通常2个)中找到最长公共子序列(注意:不同于子串,LCS不需要是连续的子串)。该问题是典型的计算机科学问题,是文件差异比较程序的基础,在生物信息学中也有所应用。
https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
样例
样例 1:

输入:

A = "ABCD"
B = "EDCA"
输出:

1
解释:

LCS'A''D''C'
样例 2:

输入:

A = "ABCD"
B = "EACB"
输出:

2
解释:

LCS"AC""AB"

参考答案

public class Solution {
    /**
     * @param a: A string
     * @param b: A string
     * @return: The length of longest common subsequence of A and B
     */
    public int longestCommonSubsequence(String a, String b) {
        if (a == null || b == null || a.length() == 0 || b.length() == 0)
            return 0;
        //单纯递归,超时
        //int ans = dfs1(a.toCharArray(), b.toCharArray(), a.length() - 1, b.length() - 1);

        //动态规划,或者递归+缓存也行,这里先用动态规划来做
        int ans = dfs2(a.toCharArray(), b.toCharArray());

        return ans;
    }

    public static int dfs1(char[] str1, char[] str2, int i, int j) {
        if (i == 0 && j == 0) {
            return str1[i] == str2[j] ? 1 : 0;
        } else if (i == 0) {
            if (str1[i] == str2[j]) {
                return 1;
            } else {
                return dfs1(str1, str2, i, j - 1);
            }
        } else if (j == 0) {
            if (str1[i] == str2[j]) {
                return 1;
            } else {
                return dfs1(str1, str2, i - 1, j);
            }
        } else {
            int p1 = dfs1(str1, str2, i - 1, j);
            int p2 = dfs1(str1, str2, i, j - 1);
            int p3 = str1[i] == str2[j] ? (1 + dfs1(str1, str2, i - 1, j - 1)) : 0;

            return Math.max(p1, Math.max(p2, p3));
        }
    }

    public static int dfs2(char[] str1,char[] str2){
        int n =str1.length;
        int m = str2.length;
        int[][] dp = new int[n+1][m+1];
        dp[0][0]= str1[0]==str2[0]?1:0;
        for (int i = 1; i <m ; i++) {
            dp[0][i] = str1[0] == str2[i]?1:0;
        }
        for (int i = 1; i <n ; i++) {
            dp[i][0] = str1[i] == str2[0]?1:0;
        }

        int ans = 0;
        for (int i = 1; i <n ; i++) {
            for (int j = 1; j <m ; j++) {
                int p1 = dp[i-1][j];
                int p2 = dp[i][j-1];
                int p3 = str1[i]==str2[j]?(1+dp[i-1][j-1]):0;

                dp[i][j] = Math.max(p1,Math.max(p2,p3));
            }
        }
        return dp[n-1][m-1];
    }
}

你可能感兴趣的:(动态规划,算法)