最长公共子序列(Longest-Common-Subsequence)

最长公共子序列属于动态规划中比较经典的题目,但是leetcode上好像没有这题,所以把这题的代码存放到简书。

LintCode本题链接
题目描述:给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。
说明
最长公共子序列的定义:

最长公共子序列问题是在一组序列(通常2个)中找到最长公共子序列(注意:不同于子串,LCS不需要是连续的子串)。该问题是典型的计算机科学问题,是文件差异比较程序的基础,在生物信息学中也有所应用。
维基百科关于LCS的介绍

样例

给出"ABCD" 和 "EDCA",这个LCS是 "A" (或 D或C),返回1

给出 "ABCD" 和 "EACB",这个LCS是"AC"返回 2

方法一 递归(超时)

   public int longestCommonSubsequence(String str1,String str2){
        return longestCommonSequence(str1,str1.length()-1,str2,str2.length()-1,0);
    }

    private int longestCommonSubsequence(String str1, int index1, String str2, int index2,int count){
        if(index1<0||index2<0) return count;
        if(str1.charAt(index1)==str2.charAt(index2)){
            count++;
            return longestCommonSequence(str1,index1-1,str2,index2-1,count);
        }else{
            return Math.max(longestCommonSequence(str1,index1-1,str2,index2,count),
                            longestCommonSequence(str1,index1,str2,index2-1,count));
        }
    }

方法二 动态规划(自底向上)

public int longestCommonSubsequence(String str1, String str2) {
        if(str1.isEmpty()||str2.isEmpty()) return 0;
        int m=str1.length(), n=str2.length();
        int[][] dp = new int[m+1][n+1];
        for(int i=1; i<=m; i++){
            for(int j=1; j<=m; j++){
                if(str1.charAt(i-1)==str2.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1]+1;
                }else{
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        return dp[m][n];
    }

推荐阅读更多精彩内容