找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。其实这又是一个序贯决策问题,可以用动态规划来求解。我们采用一个二维矩阵来记录中间的结果。这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab")
b a b
c 0 0 0
a 0 1 0
b 1 0 1
a 0 1 0
我们看矩阵的斜对角线最长的那个就能找出最长公共子串。
不过在二维矩阵上找最长的由1组成的斜对角线也是件麻烦费时的事,下面改进:当要在矩阵是填1时让它等于其左上角元素加1。
b a b
c 0 0 0
a 0 1 0
b 1 0 2
a 0 2 0
这样矩阵中的最大元素就是 最长公共子串的长度。
矩阵更新的过程可以简化到一个一位数组,代码如下:
public class LCString {
public String LCS(String str1, String str2) {
int m = str1.length();
int n = str2.length();
int[] count = new int[m];
int max = 0;
int pos = 0;
for (int i = 0; i < n; i++) {
char c = str2.charAt(i);
for (int j = m - 1; j >= 0; j--) {
if (str1.charAt(j) == c) {
if (j == 0)
count[j] = 1;
else
count[j] = count[j - 1] + 1;
if (count[j] > max) {
max = count[j];
pos = j;
}
} else {
count[j] = 0;
}
}
}
return str1.substring(pos - max + 1, pos + 1);
}
}