读书笔记之 LCS 最大公共序列

LCS最大公共序列,即A,B字符串中的最大公共部分,可以是不连续的。

这块代码分为两部分,两部分的时间复杂度是一样的,都是O(N*N),空间复杂度有不同


假设dij为A字符串取i个字符,B字符串取j个字符后对应俩字符串的LCS的长度。

那么:

当i=0或者j=0的时候,显然dij=0;

i!=0且j!=0,并且a[i]=b[j],此时dij=d(i-1)(j-1)+1;

i!=0且j!=0,并且a[i]!=b[j],此时dij=max(di(j-1),d(i-1)j).此即为LCS的DP公式。

据此可以写出代码:

int LCS()
{
for(int i =1;i<=LEN1;++i)
for(int j =1;j<=LEN2;++j)
{
if(a[i-1] == b[j-1])
d[i][j] = 1+d[i-1][j-1];
else
{
d[i][j] = d[i-1][j]>d[i][j-1]?d[i-1][j]:d[i][j-1];
}


cout<<"<i,j>"<<i<<" "<<j<<" "<<d[i][j]<<endl;
}
return d[LEN1][LEN2];
}


另外,可以看出,对i进行循环时,j已经进行了轮次循环。

换句话说,i=2时,i=0的对应的d[i][j]已经是用不到了;i=3时,i=1对应的d[i][j]已经是用不到了。

这个时候可以把dN*N矩阵缩小为DN*2.循环使用两列,空间复杂度为O(2N)。

对应代码为

int LCS2()
{
int k;
for(int i =1;i<=LEN1;++i)
for(int j =1;j<=LEN2;++j)
{
k = i&1;
if(a[i-1] == b[j-1])
d[k][j] = 1+d[k^1][j-1];
else
{
d[k][j] = d[k^1][j]>d[k][j-1]?d[k^1][j]:d[k][j-1];
}


cout<<"<i,j>"<<i<<" "<<j<<" "<<d[k][j]<<endl;
}
return d[k][LEN2];
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值