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

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

最长公共子串 | DP-29

最长公共子串问题是计算两个串的最长公共部分的问题,例如字符串“abcsddjsijsd”和“abcissijksd”最长公共子串是sij。

解题思路

采用动态规划(Dynamic Programming)的思想解决该问题。定义动态规划数组 dp[i][j] 表示以 A[i] 和 B[j] 为结尾的最长公共子串的长度。其中 A、B 分别为两个字符串,i 和 j 分别为 A、B 中字符的下标。

当 A[i] == B[j] 时,dp[i][j] = dp[i-1][j-1] + 1;否则 dp[i][j] = 0

最终最长公共子串的长度为 max(dp[i][j]),其中 i 和 j 为数组 dp 中最大值所对应的下标。

代码实现

使用 Python 语言实现动态规划算法:

def longest_common_substring(A, B):
    m, n = len(A), len(B)
    dp = [[0] * (n+1) for _ in range(m+1)]  # 初始化动态规划数组

    longest, end = 0, 0  # 初始化最长公共子串的长度和结尾位置

    for i in range(1, m+1):
        for j in range(1, n+1):
            if A[i-1] == B[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1

                if dp[i][j] > longest:
                    longest = dp[i][j]
                    end = i

    return A[end-longest : end]
性能分析

时间复杂度为 $O(mn)$,空间复杂度为 $O(mn)$,其中 m 和 n 分别为 A 和 B 的长度。

使用示例
A = 'abcsddjsijsd'
B = 'abcissijksd'
print(longest_common_substring(A, B))  # 输出 'sij'
参考资料