1.8 动态规划之最大公共子串问题。

给定两个字符串,str1、str2,求返回俩字符串最长公共子串。

分析:
1)本题与求最长公共子序列相似,但又有所不同。在求子序列问题中,动态规划通式i、j位置的值取决于三个位置,dp[i-1][j-1] dp[i-1][j] dp[i][j-1], 三者中,
2)先假设最后一个字符相等,纳入最长子序列中,那么如果只改变一个变量,不论是i或者是j加一,因为原有子序列已达到最长且最边界的情况,只增加其中一个序列是无法影响最长公共子序列的,此时i、j都增加一个元素且该元素相等才有可能会影响
3)最后一个字符不相等,那没什么好说的,两边i、j各自减去一个字符的最长子序列的最大值便是i、j的最长子序列值。
4)在本题中,求最长公共子串,若按照求子序列一样的参数设置显然不行,子串是连续的,此时dp[][]表格中的数据应该代表什么?子串是连续的数据,那么我们在已知的数据前提下,对i、j进行增加,所得到的新的数据i+1、j+1需要与i、j紧密联系,那么只有i、j的值相等,这样i+1、j+1才会对原来的数值有影响,如此可得出表中数据应该为,以i、j为最后一个公共子串元素的情况下,最长公共子串的长度。
5)由4)得出,dp[i][j]的数据代表着以元素str1[i] str2[j]为尾节点的情况下,最长公共子串的长度值,那么我们可以轻易得出,[i+1][j+1]处的值仅取决于str1[i+1] == str2[j+1] ? 相等则用i、j位置的值+1,不相等则为 [i-1][j]和[i][j-1]位置的值取较大值

代码实现:
1)本题中,能否通过常规动态规划的方法压缩空间?
尝试列出随意一个矩阵,不难发现,矩阵中数列呈斜线状排列。尝试推导:也没啥好推导的,就忒明显了,从公式和数据上看都非常明显。

public String list(String str1 , String str2){
	int left = 0;	//从右上方往左移,移动到0之后开始往下移
	int right = str2.length - 1;  	//行数
	int col = str1.length;		//列数
						//这里行数要减一,是因为为了压缩空间,我们选择斜线状来填写数据,此时只需要常数个空间变量来存储。
	
	int max = 0;
	int cur = 0;
	int end = 0; //用于存储最大公共子串的尾节点下标

	while(left < col){
		//开始都是0
		int len = 0;
		int i = left;
		int j = right;
		//得先记录不等于的情况?
		//这里还有一个循环,是往斜下方遍历
		while(i < str1.length && j < str2.length){
			if(str1[i] != str2[j]){
				len = 0;
			}else{
				len++;
			}
			//最大值的更新
			if(len > max){
				max = len;
				end = i;
			}
			i++;
			j++
		}//这里斜下方遍历完,开始移动
		if(right > 0){
			right--;
		}else{
			left++;
		}
	return str1.substring(end-max-+1,end+1);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值