一、问题果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则S 称为已知序列的最长公共子序列,即求最长公共子序列。
二、分析
(1)穷举法
(2)动态规划
Xi=﹤x1,⋯,xi﹥即X序列的前i个字符 (1≤i≤m)
Yj=﹤y1,⋯,yj﹥即Y序列的前j个字符 (1≤j≤n)
若xm=yn(最后一个字符相同),则不难用反证法证明:该字符必是X与Y的任一最长公共子序列Z(设长度为k)的最后一个字符,即有zk = xm = yn 且显然有Zk-1∈LCS(Xm-1 , Yn-1)即Z的前缀Zk-1是Xm-1与Yn-1的最长公共子序列。此时,问题化归成求Xm-1与Yn-1的LCS(LCS(X , Y)的长度等于LCS(Xm-1 , Yn-1)的长度加1)。
若xm≠yn,则亦不难用反证法证明:要么Z∈LCS(Xm-1, Y),要么Z∈LCS(X , Yn-1)。由于zk≠xm与zk≠yn其中至少有一个必成立,若zk≠xm则有Z∈LCS(Xm-1 , Y),类似的,若zk≠yn 则有Z∈LCS(X , Yn-1)。此时,问题化归成求Xm-1与Y的LCS及X与Yn-1的LCS。LCS(X , Y)的长度为:max{LCS(Xm-1 , Y)的长度, LCS(X , Yn-1)的长度}。
二、代码设计、
Lcs(A,B,L){//字符串A,B,所求矩阵L
for(k=1;k<=m;k++){ //m 为A 的长度
for(i=1;i<=m;i++){
if(i<k) L[k][i]=N;//i<k 时,L(k,i)=null,N 代表无穷大
if(L[k][i]==k)//L(k,i)=k 时,L(k,i+1)=L(k,i+2)=…L(k,m)=k
for(l=i+1;l<=m;l++)
{ L[k][l]=k;
Break;}
for(j=1;j<=n;j++){//定理4 的实现
if(A[i+1]==B[j]&&j>L[k-1][i]){
L[k][i+1]=(j<L[k][i]?j:L[k][i]);
break;
}
if(L[k][i+1]==0)
L[k][i]=N;
}
if(L[k][m]==N)
{p=k-1;break;}
}
p=k-1;
}
三、时间复杂度、
O(nlogn);
四、源代码、
https://github.com/yttb/hello-world