📜  最长的公共子串| DP-29(1)

📅  最后修改于: 2023-12-03 15:40:17.303000             🧑  作者: Mango

最长的公共子串

最长的公共子串问题是指在两个或多个字符串中找到最长的相同子串。这个问题可以使用动态规划算法来解决。

动态规划解法

我们可以使用动态规划来解决最长的公共子串问题。定义一个二维数组 dp,其中 dp[i][j] 表示以第一个字符串的第 i 个字符和第二个字符串的第 j 个字符结尾的最长公共子串的长度。

转移方程如下:

dp[i][j] = dp[i-1][j-1] + 1, if s1[i-1]==s2[j-1]
dp[i][j] = 0, otherwise

其中, s1s2 分别为两个字符串。如果 s1[i-1]==s2[j-1],则子串可以继续扩展,即 dp[i][j] 的值为 dp[i-1][j-1] + 1,否则子串不再相同,即 dp[i][j] 的值为 0。

最后,我们只需要在 dp 数组中找到最大的值,即可得到两个字符串的最长公共子串的长度。

代码实现如下:

def longest_common_substring(s1, s2):
    m, n = len(s1), len(s2)
    dp = [[0] * (n+1) for _ in range(m+1)]
    max_len = 0
    for i in range(1, m+1):
        for j in range(1, n+1):
            if s1[i-1] == s2[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
                max_len = max(max_len, dp[i][j])
    return max_len

时间复杂度为 $O(mn)$,其中 $m$ 和 $n$ 分别为两个字符串的长度。

示例

假设有两个字符串 s1 = "abcdefg"s2 = "zbcdfg",它们的最长公共子串为 "bcdefg",长度为 6。

我们可以使用上面的动态规划解法来求解这个问题:

>>> s1 = "abcdefg"
>>> s2 = "zbcdfg"
>>> longest_common_substring(s1, s2)
6
总结

动态规划算法是解决最长的公共子串问题的常见方法。通过定义二维数组 dp,并使用转移方程来更新数组中的元素,可以解决这个问题。时间复杂度为 $O(mn)$,其中 $m$ 和 $n$ 分别为两个字符串的长度。