最长公共子序列(LCS)

给定两个字符串,求两个字符串的最大长共子序列,比如A1B45CD,12AB67C,所以这两个字符串的公共子字符串为ABC。注意公共子序列和公共子字符串区别。

求法分两步,第一步求出最长公共子序列的长度,第二步,根据最长长度回溯求出其中对应的子序列。

代码:

public class Main {
    //生成dp数组
    public static int[][] getdp(char[] c1, char[] c2) {
        
        int len1 = c1.length;
        int len2 = c2.length;
        
        int[][] dp = new int[len1][len2];
        
        dp[0][0]= c1[0]==c2[0] ? 1:0;
        
        
        //第一行填充
        for(int j=1; j<len2; j++) {
            dp[0][j] = Math.max(dp[0][j-1], c1[0]==c2[j] ? 1 : 0);
        }
        
        //第一列填充
        for(int i=1; i<len1; i++) {
            dp[i][0] = Math.max(dp[i-1][0], c1[i]==c2[0] ? 1 : 0);
        }
        
        for(int i=1; i<len1; i++) {
            for(int j=1; j<len2; j++) {
                dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
                if(c1[i] == c2[j]) {
                    dp[i][j] = Math.max(dp[i][j], dp[i-1][j-1]+1);
                }
            }
        }return dp;
    }
    
        //最长公共子序列Longest Common Subsequence
    public static String lcs(String s1, String s2) {
        if(s1==null || s1.length()==0 || s2==null || s2.length()==0) {
            return null;
        }
        char[] c1 = s1.toCharArray();
        char[] c2 = s2.toCharArray();
        
        int[][] dp = getdp(c1, c2);
        
        int row = dp.length-1;
        int col = dp[0].length-1;
        
        int longestNum = dp[row][col]-1;
        
        char[] res = new char[dp[row][col]];
        
        while(longestNum>=0) {
                if(row>0 && dp[row][col] == dp[row-1][col]) {
                    row--;
                } else if(col>0 && dp[row][col] == dp[row][col-1]){
                    col--;
                } else {
                    res[longestNum--] = c1[row];
                    row--;
                    col--;
                }
            }
        
        return String.valueOf(res);
    }
    
    public static void main(String[] args) {
        String s1 = "1A2C3D4B56";
        String s2 = "B1D23CA45B6A";
        
        System.out.println(lcs(s1, s2));
    }
}
原文地址:https://www.cnblogs.com/loren-Yang/p/7503922.html