字符串a,长度为m:a[1].a[2].a[3].a[4]....a[m]

字符串b,长度为n:b[1].b[2].b[3].b[4]....b[n]

比如字符串a:BDCABA;字符串b:ABCBDAB则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA或者BDAB,可以不用连续

1.求字符串a:0~m和b:0~n的最长公共子序列,如果a[m]等于b[n],问题是不是转化为求a:0~m-1和b:0~n-1的最长公共子序列(再加上a[m]或者b[n]的这个字符),最长公共子序列的长度用dp[m-1][n-1]+1表示;同样的,如果a[m-1]等于b[n-1],问题转化为求a:0~m-2和b:0~n-2的最长公共子序列+2,用dp[m-2][n-2]+2表示;

2.如果a[m]不等于b[n],说明最后一个元素不可能是最长公共子序列中的元素(都不相等了,怎么公共嘛),那对于最长公共子序列来说,可能是a[m-1]和b[n]的最长公共子序列或者a[m]和b[n-1]的最长公共子序列;同理要判断a[m-1]和b[n],如果a[m-1]和b[n]不相等,那继续递推a[m-1]和b[n-1]和a[m-2]和b[n];a[m]和b[n-1]是不是相等,如果a[m]和b[n-1]不相等,那继续递推a[m-1]和b[n-1]和a[m]和b[n-2];

.......

3.如果m=0,也即字符串a的长度是0,不管b字符串的情况怎样,那最长公共子序列肯定是0,记d[0][n]=0;同理,b字符串的长度为0时,d[m][0]=0;

即 if(a[m]==b[n]) dp[m][n] = dp[m-1][n-1]+1;

    if(a[m]!=b[n]) dp[m][n] = max{dp[m-1][n], dp[m][n-1]};

    if(m==0||n==0) dp[m][n]=0;

4.构建二维数组,dp[m][n]的值就是要求的最长公共子序列长度,如下图中的dp[6][7]=4

5.同样,根据上图,找到最长公共子序列BCBA或者BDAB

BCBA或者BDAB

6.代码部分

 1 public static void lcs(String x, String y) {
 2         if(x==null||"".equals(x)||y==null||"".equals(y)){
 3             return;
 4         }
 5         //记录通过哪个子问题解决的,也就是递推的路径
 6         int[][] pos = new int[x.length()+1][y.length()+1];
 7         int[][] dp = new int[x.length() + 1][y.length() + 1];
 8         int maxLength = 0;
 9         for (int i = 1; i < x.length() + 1; i++) {
10             for (int j = 1; j < y.length() + 1; j++) {
11                 if (x.charAt(i - 1) == y.charAt(j - 1)) {
12                     dp[i][j] = dp[i - 1][j - 1] + 1;
13                 } else {
14                     if(dp[i-1][j] >= dp[i][j-1]){
15                         dp[i][j] = dp[i-1][j];
16                         pos[i][j] = 1;
17                     }else{
18                         dp[i][j] = dp[i][j-1];
19                         pos[i][j] = -1;
20                     }
21                 }
22                 maxLength = Math.max(dp[i][j], maxLength);
23             }
24         }
25         System.out.println("公共子序列长度:"+maxLength);
26         System.out.println("公共子序列:");
27         printLCS(pos, x, x.length(), y.length());
28         System.out.println();
29     }
30 
31     public static void printLCS(int[][]b,String x,int i,int j){
32         if(i == 0 || j == 0){
33             return;
34         }
35         if(b[i][j] == 0){
36             printLCS(b,x,i-1,j-1);
37             System.out.print(x.charAt(i-1));
38         }else if(b[i][j] == 1){
39             printLCS(b,x,i-1,j);
40         }else{
41             printLCS(b,x,i,j-1);
42         }
43     }
java