Given two strings, find the longest common substring.
Return the length of it.
Example
Given A = "ABCD"
, B = "CBCE"
, return 2
.
Challenge
O(n x m) time and memory.
Notice
The characters in substring should occur continuously in original string. This is different with subsequence.
LintCode:链接
最长公共子序列:链接
参考链接:动态规划
该题问的是最长公共子串,最长公共子串比最长公共子序列的递推公式要简单一些。最长公共子串必须是连续的。
dp[i][j]的含义也发生了变化:
1)在最长公共子序列中,dp[i][j]表示str_a[1:i]和str_b[1:j]的最长公共子序列,是从str_a的1和str_b的1开始计算的,即整个字符串的起始位置。
2)在最长公共子串中,dp[i][j]表示str_a[i':i]和str_b[j':j]的最长公共子串,因为str_a和str_b可能存在多个公共子串,所以i'和j'分别表示当前公共子串的起始位置。
也就是说:
-
当str_a[i] == str_b[j]时,dp[i][j] = dp[i-1][j-1]+ 1;
-
当str_a[i] != str_b[j]时,dp[i][j] = 0,即开始计算新的公共子串。
和最长公共子序列不同的是,在最长公共子串问题中,dp[m][n]不一定是最终结果,比如“abcdxy”和“abcfxy”,dp[m][n]存储的是公共子串“xy”的长度,而不是公共子串“abc”的长度,所以需要一个变量单独记录最长子串的长度。
该时间复杂度是O(mn),空间复杂度是O(mn),空间复杂度可以进一步优化,见上方参考链接。
class Solution:
"""
@param A: A string
@param B: A string
@return: the length of the longest common substring.
"""
def longestCommonSubstring(self, A, B):
# write your code here
m, n = len(A), len(B)
if m == 0 or n == 0:
return 0
dp = [[0] * (n+1) for i in range(m+1)]
max_length = 0
LCS = ""
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] > max_length:
max_length = dp[i][j]
LCS = A[i-max_length:i]
else:
dp[i][j] = 0
print(LCS)
return max_length