在DP应用中,有一类的问题是使用两个数组串作为输入,最长公共子串问题就是其中的一个,其题面为
给定两个字符串text1和text2,返回这两个字符串的最长公共子串的长度。
实例如下:
text1 = "abcdxyz",text2 = "xyzabcd"
答案是4,最长公共子串是"abcd"。
解题思路:
针对俩个输入参数,我们定义一个DP表达式F(i, j), 其中i和j分别是两个字符串的数组下标,F(i, j)返回的是text1中前i个字符和text2中前j个字符之间的最长公共子串长度。F(i, j)的返回值有两种情况,当text1[i]和text2[j]相等时,F(i, j)的返回值等于1+F(i + 1, j + 1),而当text1[i]和text2[j]不等时,F(i, j)的返回值则是0。
从以上表达式出发,我们使用一个二维的DP数组,以及双重循环,对text1和text2的数组下标分别按从大到小的顺序依次计算DP数组中的各个元素的值,同时使用一个变量来记录最长的公共子串长度,当循环完成后,该变量中的数值就是问题的答案。
Java代码如下
class Solution {
public int longestCommonSubstring(String s1, String s2) {
char[] chars1 = s1.toCharArray();
int N1 = chars1.length;
char[] chars2 = s2.toCharArray();
int N2 = chars2.length;
int[][] dp = new int[N1 + 1][N2 + 1];
int result = 0;
for (int i = 1; i <= N1; i ++) {
for (int j = 1; j <= N2; j ++) {
if (chars1[i - 1] == chars2[j - 1]) {
dp[i][j] = 1 + dp[i - 1][j - 1];
result = Math.max(result, dp[i][j]);
}
}
}
return result;
}
}