牛客刷题——最长公共子串

题目:给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1。

输入:"1AB2345CD","12345EF" 

输出:"2345"

看完题目想到了用动归,刚开始分析的时候想着,对于每两个元素的比较,有两种情况,1.元素相同,那么当前元素能够成的最长公共子串的长度为上一个的+1;2.元素不相同,那么构成的最长公共子串长度为0。但是没有考虑清楚,对于情况1 的上一个元素是什么样的,动归计算出来的是一个序列还是一个二维矩阵。。。。总之也算是有点进步了,嗯。

在进行最长公共子串判断的时候,由于两个子串中的任何位置都可能存在匹配,因此需要使用两层循环进行遍历,计算出动归矩阵。对于当前位置 [i,j],如果两个子串中 i 和 j 位置的元素对应相等,那么构成一位的公共子串,此时就需要去看看两个子串的对应上个元素是不是相等的,对于 i ,其前面一个元素是 i-1,对于 j ,前面一个元素是 j-1,所以 [i,j] 的值应该为 1+[i-1,j-1],如果当前元素不匹配的话,那么[i,j]直接置为0即可。

在进行计算矩阵的时候,由于字符串的第一个元素没有前置元素,因此可以添加一零行和 一零列来保证第一个元素也有前置状态可循。并且在计算矩阵的过程中,每次遇到对应元素匹配的时候,更新当前的最大长度max和最大长度对应的下标maxIndex,在后面获取最长子串的时候可以直接使用substring函数,根据最大长度和最大的下标确定起始点maxIndex-max+1,确定结束点maxIndex+1进行截取即可。

完整代码如下:

public static String LCS (String str1, String str2) {
        // write code here
        if(str1==null||str2==null||str1.equals("")||str2.equals("")){
            return "-1";
        }
		int len1 = str1.length()+1;
		int len2 = str2.length()+1;
		int[][] res = new int[len1][len2];
		int max = 0;
        int maxIndex = 0;
		for(int k=0;k<len2;k++) {
			res[0][k]=0;
		}
		for(int k=0;k<len1;k++) {
			res[k][0]=0;
		}
		for(int i=1;i<len1;i++) {
			for(int j=1;j<len2;j++) {
				if(str1.charAt(i-1)==str2.charAt(j-1)) {
					res[i][j] = res[i-1][j-1]+1;
					if(res[i][j]>max) {
						max = res[i][j];
                        maxIndex = i-1;
					}
				}else {
					res[i][j] = 0;
				}
			}
		}
		if(max==0){
            return "-1";
        }else{
            return str1.substring(maxIndex-max+1,maxIndex+1);
        }
		
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值