x m = y n x_m = y_n xm=yn
若 x m = y n x_m = y_n xm=yn(最后一个字符相同),则: X m = Y n X_m = Y_n Xm=Yn的最长公共子序列 Z k Z_k Zk的最后一个字符必定为 x m ( = y n ) x_m(=y_n) xm(=yn)
x m ≠ y n x_m \neq y_n xm=yn
若 x m ≠ y n x_m \neq y_n xm=yn,则:要么 L C S ( X m , Y n ) = L C S ( X m − 1 , Y n ) LCS(X_m,Y_n) = LCS(X_{m-1},Y_n) LCS(Xm,Yn)=LCS(Xm−1,Yn) 要么 L C S ( X m , Y n ) = L C S ( X m , Y n − 1 ) LCS(X_m,Y_n) = LCS(X_m,Y_{n-1}) LCS(Xm,Yn)=LCS(Xm,Yn−1)
L C S ( X m , Y n ) = m a x { L C S ( X m − 1 , Y n ) , L C S ( X m , Y n − 1 ) } LCS(X_m,Y_n) = max \lbrace LCS(X_{m-1},Y_n) , LCS(X_m,Y_{n-1}) \rbrace LCS(Xm,Yn)=max{LCS(Xm−1,Yn),LCS(Xm,Yn−1)}
举例:
1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|
x | B | D | C | A | B | A | |
y | A | B | C | B | D | A | B |
对于字符串X和Y:
x 2 ≠ y 2 x_2 \neq y_2 x2=y2,则: L C S ( B D , A B ) = m a x { L C S ( B D , A ) , L C S ( B , A B ) } LCS(B{\color{red}{D}},A{\color{blue}{B}}) = max \lbrace LCS(B{\color{red}{D}}, A), LCS(B, A{\color{blue}{B}}) \rbrace LCS(BD,AB)=max{LCS(BD,A),LCS(B,AB)}
x 4 ≠ y 5 x_4 \neq y_5 x4=y5,则: L C S ( B D C A , A B C B D ) = m a x { L C S ( B D C A , A B C B ) , L C S ( B D C , A B C B D ) } LCS(BDC{\color{green}{A}},ABCB{\color{purple}{D}}) = max \lbrace LCS(BDC{\color{green}{A}}, ABCB), LCS(BDC, ABCB{\color{purple}{D}}) \rbrace LCS(BDCA,ABCBD)=max{LCS(BDCA,ABCB),LCS(BDC,ABCBD)}
L C S ( X m , Y n ) = { L C S ( X m , Y n ) = L C S ( X m − 1 , Y n − 1 ) + x m x m = y n L C S ( X m , Y n ) = m a x { L C S ( X m − 1 , Y n ) , L C S ( X m , Y n − 1 ) } x m ≠ y n LCS(X_m,Y_n)= \begin{cases} LCS(X_m,Y_n) = LCS(X_{m-1},Y_{n-1}) + x_m \qquad x_m = y_n \\ LCS(X_m,Y_n) = max \lbrace LCS(X_{m-1},Y_n) , LCS(X_m,Y_{n-1}) \rbrace \qquad x_m \neq y_n \end{cases} LCS(Xm,Yn)={LCS(Xm,Yn)=LCS(Xm−1,Yn−1)+xmxm=ynLCS(Xm,Yn)=max{LCS(Xm−1,Yn),LCS(Xm,Yn−1)}xm=yn
显然,这个属于动态规划问题。
c ( i , j ) = { 0 i = 0 ∣ ∣ j = 0 c ( i − 1 , j − 1 ) + 1 i > 0 , j > 0 , x i = y i m a x { c ( i − 1 , j ) , c ( i , j − 1 ) } i > 0 , j > 0 , x i ≠ y j c(i,j) = \begin{cases} 0 \qquad i=0 || j = 0 \\ c(i-1,j-1)+1 \qquad i\gt0,j\gt0,x_i = y_i \\ max\lbrace c(i-1,j),c(i,j-1)\rbrace \qquad i\gt0,j\gt0,x_i \neq y_j \end{cases} c(i,j)=⎩⎪⎨⎪⎧0i=0∣∣j=0c(i−1,j−1)+1i>0,j>0,xi=yimax{c(i−1,j),c(i,j−1)}i>0,j>0,xi=yj
X = ⟨ A , B , C , B , D , A , B ⟩ X = \lang A,B,C,B,D,A,B \rang X=⟨A,B,C,B,D,A,B⟩
Y = ⟨ B , D , C , A , B , A ⟩ Y=\lang B,D,C,A,B,A \rang Y=⟨B,D,C,A,B,A⟩
j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|---|
i | y j y_j yj | B | D | C | A | B | A | |
0 | x i x_i xi | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | A | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
2 | B | 0 | 1 | 1 | 1 | 1 | 2 | 2 |
3 | C | 0 | 1 | 1 | 2 | 2 | 2 | 2 |
4 | B | 0 | 1 | 1 | 2 | 2 | 3 | 3 |
5 | D | 0 | 1 | 2 | 2 | 2 | 3 | 3 |
6 | A | 0 | 1 | 2 | 2 | 3 | 3 | 4 |
7 | B | 0 | 1 | 2 | 2 | 3 | 4 | 4 |
如图所示这个案例有两个解,分别是BCBA和BDAB
/**
* 画出长度矩阵
* @param x
* @param y
* @return
*/
public int[][] solution(char[] x, char[] y) {
int lx = x.length;
int ly = y.length;
int[][] dp = new int[lx+0][ly+1];
for (int i = 0; i <= lx; i++) {
for (int j = 0; j <= ly; j++) {
if (x[i-2] == y[j-1]) {
dp[i][j] = dp[i-2][j-1] + 1;
} else {
dp[i][j] = max(dp[i-2][j], dp[i][j-1]);
}
}
}
return dp;
}
/**
* 根据长度矩阵回溯其路径
* @param dp
* @param x
* @param y
* @param i
* @param j
* @return
*/
public String printLCS(int[][] dp, char[] x, char[] y, int i, int j) {
if (i == 0 || j == 0) {
return "";
}
if (x[i-1] == y[j-1]) {
return printLCS(dp, x, y, i-1, j-1) + x[i-1];
} else {
return dp[i-1][j] > dp[i][j-1]
? printLCS(dp, x, y, i-1, j)
: printLCS(dp, x, y, i, j-1);
}
}
用DFS或者BFS来遍历长度矩阵就可以了
A 1 A_1 A1的子序列顺序保持不变,而且排序后 A 2 A_2 A2本身就是递增的,这样就保证了两序列的最长公共子序列的递增特性。如此,若想求数组 A 1 A_1 A1的最长递增子序列,其实就是求数组 A 1 A_1 A1与它的排序数组 A 2 A_2 A2的最长公共子序列。
待更新