算法——最长公共子串(一张图片看懂)
概述
给定str1与str2两个字符串,找出其中最长的公共子串。
思路
用str1和str2建立一个二维矩阵,很轻易的就能从中发现关系。矩阵的大小为:
int[][] dp = new int[str1.lenth()+1][str2.length()+1]
这是为了方便substring的操作而已。
下面给出图示方便理解:
代码
public class 最长公共子串 {
/**
* longest common substring
* @param str1 string字符串 the string
* @param str2 string字符串 the string
* @return string字符串
* 将str1与str2组成一个二维矩阵,相同的地方标记为1,那么可以观察到对角线处相连的1就是一个连续的公共子串;
* 为了搞到最大的值,则只需要将对角线的1不断地累加并保存即可,待矩阵构建完毕,我们就已经知道最大的子串长为多少,
* 以及在哪个index结束。
*/
public String LCS (String str1, String str2) {
//异常处理
if (str1 == null || str2 == null)
return str1 == null ? str2 : str1;
//动态规划
int len1 = str1.length(),
len2 = str2.length(),
max = 0,
index = 0;
int[][] dp = new int[len1 + 1][len2 + 1];
for (int i = 0; i < len1; i++){
for (int j = 0; j < len2; j++){
//如果字符相等,则这个子串的长度取决于之前的子串长度 + 1
if (str1.charAt(i) == str2.charAt(j)){
dp[i + 1][j + 1] = dp[i][j] + 1;
}
if (max < dp[i + 1][j + 1]){
max = dp[i + 1][j + 1];
index = i + 1;
}
}
}
//截取字符串并返回
return max == 0 ? "-1" : str1.substring((index - max),(index));
}
}