1、最长公共子序列
c[i][j]表示Xi和Yi的最长公共子序列的长度
状态转移方程:
0, i=0 || j=0
c[i][j]= c[i-1][j-1]+1, xi=yi
max(c[i-1][j],c[i][j-1]),xi != yi
代码实现:
class MaxSubSequence {
char[] ch1;
char[] ch2;
int[][] c;
int[][] s;
List<Character> result = new ArrayList<>();
Set<List<Character>> allResult = new HashSet<>();
public MaxSubSequence(String s1, String s2) {
this.ch1 = ArrayStartFromOne(s1.toCharArray());
this.ch2 = ArrayStartFromOne(s2.toCharArray());
this.c = new int[ch1.length][ch2.length];
this.s = new int[ch1.length][ch1.length];
}
public char[] ArrayStartFromOne(char[] arr) {
char[] newArr = new char[arr.length + 1];
for (int i = 0; i < arr.length; i++) {
newArr[i + 1] = arr[i];
}
newArr[0] = '0';
return newArr;
}
public int getSubSequence() {
int m = ch1.length;
int n = ch2.length;
int i, j;
// 当一列为空时,公共序列为0
for (i = 1; i < m; i++)
c[i][0] = 0;
for (j = 1; j < n; j++)
c[0][j] = 0;
for (i = 1; i < m; i++) {
for (j = 1; j < n; j++) {
if (ch1[i] == ch2[j]) {
c[i][j] = c[i - 1][j - 1] + 1;
s[i][j] = 1;
} else if (c[i - 1][j] > c[i][j - 1]) {
c[i][j] = c[i - 1][j];
s[i][j] = 2;
} else {
c[i][j] = c[i][j - 1];
s[i][j] = 3;
}
}
}
return c[m - 1][n - 1];
}
public void getLCS() {
int i = ch1.length - 1;
int j = ch2.length - 1;
while (i > 0 && j > 0) {
if (s[i][j] == 1) {
result.add(ch1[i]);
// 左斜上方前进
i--;
j--;
} else if (s[i][j] == 2) {
// 向上前进
i--;
} else {
// 向左前进
j--;
}
}
}
public int getSubSequence2() {
int m = ch1.length;
int n = ch2.length;
int[][] c = new int[m][n];// 0到m,长度为m+1
int i, j;
// 当一列为空时,公共序列为0
for (i = 1; i < m; i++) {
for (j = 1; j < n; j++) {
if (ch1[i] == ch2[j]) {
c[i][j] = c[i - 1][j - 1] + 1;
} else {
c[i][j] = Math.max(c[i - 1][j], c[i][j - 1]);
}
}
}
return c[m - 1][n - 1];
}
2、最长公共子串
转台转移方程:
0, i=0 || j=0
c[i][j]= c[i-1][j-1]+1, xi=yi
0,xi != yi
public static int maxSubLength(int[] A, int[] B) {
int m = A.length, n = B.length;
int ans = 0;
int[][] c = new int[m + 1][n + 1];
for (int i = 1; i <= A.length; i++)
for (int j = 1; j <= B.length; j++) {
if (A[i - 1] == B[j - 1]) {
c[i][j] = c[i - 1][j - 1] + 1;
ans = Math.max(c[i][j], ans);
} else {
c[i][j] = 0;
}
}
return ans;
}