一个序列S,若分别是两个或多个已知序列的子序列,且是所有符合条件序列中最长的,则S称为已知序列的最长公共子序列(LCS)。
利用最长公共子序列,可以求解出最长递增子序列问题
/*
*
* 输入:
* 1324
*
* 1234
*
* 输出: length:3
* 子序列:1 2 4
*
* 也可以用来求解最长递增子序列问题
* 将所求序列进行排序,再求LCS即可
*/
static int[][] v;
static int[][] p;
static String a;
static String b;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
a = scanner.nextLine();
b = scanner.nextLine();
cal(a, b);
get_lcs(a.length(), b.length());
}
static void cal(String a, String b) {
char[] a_arr = a.toCharArray();
char[] b_arr = b.toCharArray();
v = new int[a_arr.length + 1][b_arr.length + 1];
p = new int[a_arr.length + 1][b_arr.length + 1];
for (int i = 1; i < v.length; i++) {
for (int j = 1; j < v[0].length; j++) {
if (a_arr[i - 1] == b_arr[j - 1]) {
v[i][j] = v[i - 1][j - 1] + 1;
p[i][j] = 1;
} else if (v[i - 1][j] > v[i][j - 1]) {
v[i][j] = v[i - 1][j];
p[i][j] = 2;
// v[i][j] = Math.max(v[i - 1][j], v[i][j - 1]);
} else {
v[i][j] = v[i][j - 1];
p[i][j] = 3;
}
}
}
for (int[] i : v) {
for (int j : i) {
System.out.print(j + " ");
}
System.out.println();
}
System.out.println("最长子序列length:" + v[a_arr.length][b_arr.length]
+ "\n最长子序列:");
}
static void get_lcs(int i, int j) {
if (i == 0 || j == 0) {
return;
}
if (p[i][j] == 1) {
get_lcs(i - 1, j - 1);
System.out.print(a.charAt(i - 1) + " ");
}
if (p[i][j] == 2) {
get_lcs(i - 1, j);
}
if (p[i][j] == 3) {
get_lcs(i, j - 1);
}
}