题解 | #查找两个字符串a,b中的最长公共子串#

查找两个字符串a,b中的最长公共子串

https://www.nowcoder.com/practice/181a1a71c7574266ad07f9739f791506

题目:

提取两个字符串中最大的公共子串,并输入(先考虑求出最大子串)

动态规划思路:

1、先简单后复杂都是解题的常规思路,首先想到两个字符串都很小的情况,比如字符串长度为1,然后考虑复杂的情况。如果两个字符串都在变,思考起来肯定很乱,那我们先固定一个,比如x串的长度固定为1,y串长度未知,可能为1到n。

//场景一
String x = "a";
String y = "acabcaefabc"

假如情况如上,那么最大子串,结果是在y串索引为0,2,5,8长度为1的串。不管y串有多长,这个求解过程就是把y串中每个字符与a比较(因为x的子串就只有a一个)

2、现在加入a不固定了,它长度可能是1,2,3.......n中的一个,那我们该怎么求,假设如下场景二

//场景二
String x = "ab";
String y = "acabcaefabb"

那么这个情况怎么求呢?x串的子串有a,ab,b三种情况,如果是穷举,那么就太耗性能了,我们可以结合上一个场景考虑。

a串和b串的求解方法用场景一的就可以,这里就不考虑。

ab串才是关键,因为它是x中拿的一个子串,所以只要去y串找,就知道是不是公共子串。方式呢?其实只需要在y串中找b字符,找到了看一下它前面是不是a,如果是那么ab是公共子串。那关键来了,怎么知道b的位置前面是不是a呢?

   //动态推导
	//假设在场景一的时候给y串找到位置打上一个标记,1代表找到了a,同时也表示现在的最大子串是1
   a-c-a-b-c-a-e-f-a-b-b
   1-0-1-0-0-1-0-0-1-0-0 
   
 	//先找到b
   a-c-a-b-c-a-e-f-a-b-b
   0-0-0-1-0-0-0-0-0-1-1
 	//在找到的b时,去加上前一个位置的标记值,如果为2,那么说明前一个位置是a
     1-0-1-0-0-1-0-0-1-0-0 
+    0-0-0-1-0-0-0-0-0-1-1
=	 1-0-1-2-0-1-0-0-1-2-1
	//其实就是找b,找到b时打个标记1,这个标记需要加上前一个位置上的值(这个值是找a时打上的标记值)
	//如果还有c,就是找c,找到c后打个标记1,然后加上前一个位置的值(这个值是找b时打上的标记)

3、状态转移方程

假设f[i][j]表示x串的前i个字符,和y串的前j个字符,之间的最大公共子串长度值。

那么根据前面分析的,找不到,那不管,f[i][j] = 0;也就不处理(数组初始化为0);

找的到,那么它就是 1 加上找前一个字符时的标记值。这个值其实最大长度。

状态转移方程就是:f[i][j] = f[i-1][j-1]

例如刚才找b时,b = 1,表示前面一个字符不是a,如果子串包括这个b的话,子串最大长度只能是1;

b = 2,表示前一个字符为a,如果子串包括当前这个b的话,子串最大是2。

 for(int i = 1;i < x.length; i++){
            for(int j = 1;j < y.length; j++){
                if(x[i] == y[j]){
				  
                    num[i][j] = 1 + num[i -1][j- 1];
				  
				   //下面这步是收集最大长度值,只有大于上一次存的最大值才处理
                    if(num[i][j]>max){
                        max = num[i][j];
                        start = i-max;
                    }
                }
            }
        }

全部评论

相关推荐

头像
11-09 17:30
门头沟学院 Java
TYUT太摆金星:我也是,好几个华为的社招找我了
点赞 评论 收藏
分享
在评审的大师兄很完美:像这种一般就是部门不匹配 转移至其他部门然后挂掉 我就是这样被挂了
点赞 评论 收藏
分享
2 1 评论
分享
牛客网
牛客企业服务