题目:最长公共子串
思路:动态规划
dp[i][j]
表示str1
以i
结尾,str2
以j
结尾的最长公共子串的个数,递推公式:
- 如果
str1[i] == str2[j]
,则dp[i][j] = dp[i - 1][j - 1] + 1
- 如果
str1[i] != str2[j]
,则dp[i][j] = 0
有了这个dp
数组,如何得到具体子串呢?我们在更新dp
数组时,维护一个最大长度和最大子串的最终位置,每得到一个更长的子串,就更新最大长度和此时的位置,最后,用结尾的位置减去长度就可以得到子串的起始位置。
代码:
import java.util.*;
public class Solution {
/**
* longest common substring
* @param str1 string字符串 the string
* @param str2 string字符串 the string
* @return string字符串
*/
public String LCS (String str1, String str2) {
// write code here
int str1len = str1.length();
int str2len = str2.length();
int[][] dp = new int[str1len + 1][str2len + 1];
int maxlen = 0;
int end = 0;
for (int i = 0; i <= str1len; i ++) {
dp[i][0] = 0;
}
for (int j = 0; j <= str2len; j ++) {
dp[0][j] = 0;
}
for (int i = 1; i <= str1len; i ++) {
for (int j = 1; j <= str2len; j ++) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
if (dp[i][j] > maxlen) {
maxlen = dp[i][j];
end = i;
}
}
// else {
// dp[i][j] = 0;
// }
}
}
if (maxlen == 0) {
return "-1";
}
return str1.substring(end - maxlen, end);
}
}