最长公共子串(动态规划)

Posted 你是人间四月天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长公共子串(动态规划)相关的知识,希望对你有一定的参考价值。

引言

最长公共子串

描述

有两个字符串,通过遍历找出最长的公共连续子串。

示例

输入两个字符串
abnacty
eabtnacm

输出最长公共连续子串
nac

分析

  1. 将两个字符串分别以行和列的形式组成一个二维矩阵;
  2. 比较二维矩阵中每个点对应的行和列的字符是否相等,相等的话,值设为1,不相等则为2;
  3. 通过进一步查找,找出值为1的最长连续对角线就能找到最长公共子路

如图,给定两个字符串abcddf和acbcdf,求出其最长公共子串为 bcd

得出递推公式

//最长公共子串长度
maxLen = 0
//最长公共子串在a中的结束位置
endAIndex = 0
当 a[i] != b[j]时
  r[i] = 0
当 a[i] == b[j]时,
    若 i==0 或 j==0
        则r[i][j] = 1
    否
        r[i][j] = r[i-1][j-1] + 1

    如果r[i][j] > maxLen
        maxLen = r[i][j]
        endIndex = i

Java代码

public static String f(String s1, String s2) {
        if ("" == s1 || "" == s2) {
            return "";
        }
        //最长公共子串在S1串中的结束位置
        int endS1Index = 0;
        //最长公共子串的长度
        int maxLength = 0;
        int r[][] = new int[s1.length()][s2.length()];

        for (int i = 0; i < s1.length(); i++) {
            for (int j = 0; j < s2.length(); j++) {
                if (s1.charAt(i) != s2.charAt(j)) {
                    r[i][j] = 0;
                } else {
                    if (i == 0 || j == 0) {
                        r[i][j] = 1;
                    } else {
                        r[i][j] = r[i - 1][j - 1] + 1;
                    }
                    
                    if (maxLength < r[i][j]) {
                        maxLength = r[i][j];
                        endS1Index = i;
                    }
                }
            }
        }
        return s1.substring(endS1Index - maxLength+1, endS1Index+1);
    }

以上是关于最长公共子串(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章

[程序员代码面试指南]递归和动态规划-最长公共子串问题(DP,LCST)

算法图解:动态规划之最长公共子串,最长公共子序列

最长公共子串(动态规划)

动态规划之最长公共子串

动态规划:最长公共子串和最长公共子序列

动态规划 最长公共子序列 过程图解