Dynamic Programming学习笔记 (20) - 最长公共子串

155 阅读1分钟

在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;
    }
}