最长公共子列长度O(2*min(l1,l2))大小空间解法

现在有两个字符串s1,s2,它们的长度分别为l1,l2

我就直接写出递归式子

假如s1[i]=s2[j]时m[i][j]=m[i-1][j-1]+1,反之,m[i][j]=max(m[i-1][j],m[i][j-1]}

m[i][j]表示s1子串(从0到i位置的子串)与s2子串(从0到j位置子串)的最大公共子列长度

从上面看出来我们的存储空间需要l1,l2大小的空间,不过,我们可以看出来,我只使用三项m[i-][j-1],m[i-1][j],m[i][j-1],我们只要保存这三项即可,那么要多大的空间呢,当然是越小越好了。

如果说l1<l2,时,我从下面的代码来说明吧

for(int i=0;i<l2;i++)
	for(int j=0;j<l1;j++)
		m[i][j]=f(m[i-1][j-1],m[i-1][j],m[i][j-1]);
可以看出里面的递归关系每次变化只是一列的变化,所以只需要保留前面一列和当前列。


最后直接上源代码吧

int MaxSamelong(string s1,string s2)
{
	vector<int> pre,cur;
	string tmp;
	if(s2.size()<s1.size())
	{
		tmp=s2;
		s2=s1;
		s1=tmp;
	}
	for(int i=0;i<s1.size();i++)
	{
		if(s2[0]==s1[i])
			pre.push_back(1);
		else
			pre.push_back(0);
	}

	for(int i=0;i<s2.size();i++)
	{
		cur.push_back(pre[0]);
		for(int j=1;j<s1.size();j++)
		{
			if(s1[j]==s2[i])
				cur.push_back(pre[j-1]+1);
			else
			{
				int k=pre[j];
				if(k<cur[j-1])
					k=cur[j-1];
				cur.push_back(k);
			}
		}
		pre=cur;
		cur.clear();
	}
	return pre[s1.size()-1];
}
再上一个测试用例吧

int main()
{
	string s1("sldjoiiiiu");
	string s2("slkkkjou");
	cout<<MaxSamelong(s1,s2);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值