要点:数组lengths, flags的大小设置
package dp;
/**
* 用动态规划求最长公共子序列
* @author lk
*
*/
public class LCSLength {
/**
* 求最长公共子序列
* @param m
* @param n
* @param chars1
* @param chars2
* @param lengths
* @param flags
*/
public static void lcsLength(int m, int n, char[] chars1, char[] chars2, int[][] lengths, int[][] flags){
for(int i = 0; i <= m; i++){
lengths[i][0] = 0;
}
for(int j = 0; j <= n; j++){
lengths[0][j] = 0;
}
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
if(chars1[i-1] == chars2[j-1]){
lengths[i][j] = lengths[i-1][j-1]+1;
flags[i][j] = 1;
}else if(lengths[i-1][j] >= lengths[i][j-1]){
lengths[i][j] = lengths[i-1][j];
flags[i][j] = 2;
}else{
lengths[i][j] = lengths[i][j-1];
flags[i][j] = 3;
}
}
}
}
/**
* 逆序输出最长公共子序列
* @param m
* @param n
* @param chars1
* @param flags
*/
public static void LCS(int m, int n, char[] chars1, int[][] flags){
if(n == 0 || n == 0) return;
if(flags[m][n] == 1){
System.out.print(chars1[m-1]+" ");
LCS(m-1, n-1, chars1, flags);
}else if(flags[m][n] == 2){
LCS(m-1, n, chars1, flags);
}else{
LCS(m, n-1, chars1, flags);
}
}
// bcab
public static void main(String[] args){
String str1 = "abcbdab";
String str2 = "bdcaba";
char[] chars1 = str1.toCharArray();
char[] chars2 = str2.toCharArray();
int m = chars1.length;
int n = chars2.length;
int[][] lengths = new int[m+1][n+1];
int[][] flags = new int[m+1][n+1];
lcsLength(m, n, chars1, chars2, lengths, flags);
System.out.println(lengths[m][n]);
LCS(m,n,chars1,flags);
}
}