最长公共子序列算法解析

/*转自网上总结*/
一、最长公共子序列(Longest Common Subsequence:LCS)

设有两个序列A[1...m]和B[1...n],分别对A和B进行划分子序列
A[1] A[1..2] A[1..3] ... A[1..m]
B[1] B[1..2] B[1..3] ... B[1..n]
依次求出A中的每个子序列(从A[1]开始)与B中每个子序列的最长公共子序列,并记录在数组C[m][n]中,C[i][j]表示A[1..i]和B[1..j]的最长公共子序列的长度。

递推公式如下:
①C[i][j]=0 i=0 or j=0
②C[i][j]=C[i-1][j-1]+1 i!=0 and j!=0 and A[i]=B[j]
③C[i][j]=max{C[i-1][j],C[i][j-1]} i!=0 and j!=0 and A[i] != B[j]

路径记录:
记录路径即记录C[i][j]是怎么得来的,从递推公式②③知,C[i][j]的来源有三个:C[i-1][j-1],C[i-1][j],C[i][j-1]。如果是从C[i-1][j-1]得来,那么A[i]=B[j],是最长公共子序列中的一个元素。
可以设置一个数组P[m][n]来记录当前的C[i][j]是怎么得来的,P[m][n]的取值只能有三种,分别记为1 2 3。

构造最长公共子序列:
用递归的方法,检查P[i][j],初始i=m,j=n
如果p[i][j]=1,则记录C[i][j],然后递归处理P[i-1][j-1]
如果P[i][j]=2,不记录,递归处理P[i-1][j]
如果P[i][j]=3,不记录,递推处理P[i][j-1]
直到i=0 or j=0

时间复杂度:O(mn)
原文地址:https://www.cnblogs.com/okboy/p/3223450.html