3

我找到了Longest Common Substring的算法。通常使用dynamic programming,使用大小为 的二维数组来完成,mxn其中mn是所考虑的两个字符串的长度。

我将为这两个字符串构造以下​​矩阵。

M[i][j] = 1 if s1[i]==s2[j] else 0.

例如,如果字符串是:abcxypqaabx

矩阵如下所示:

    a b c x y
 p  0 0 0 0 0
 q  0 0 0 0 0
 a  1 0 0 0 0
 a  1 0 0 0 0
 b  0 1 0 0 0
 x  0 0 0 1 0

1现在,我在从左上到右下方向的每个对角线中搜索 s 的最大连续序列。

其中的最大值就是答案。

我可以在不显式使用数组的情况下执行上述操作。时间复杂度仍然是O(M*N)。所以,不需要内存。

谁能指出我哪里出错了?

4

2 回答 2

1

你的方法是正确的。为了证明,假设 S1 和 S2 的最长公共子串来自 S1[i..j] 和 S2[p..q]。这意味着 S1[i+k] = S2[p+k]

这些都位于从(i,p)开始的对角线上。

动态编程解决方案做同样的事情,但不是先计算表并通过对角路径,而是根据它的对角父项加上它们是否匹配来计算表。

已编辑

关于您对使用额外内存的维基百科解决方案的评论。它只是为了清楚起见。原则上,您只需要维基百科解决方案中的两行矩阵,并将当前最大计数保留在一个变量中。这是正确的,因为对于矩阵中的任何第 (i,j) 个条目

M(i,j) = 1 + M(i-1, j-1) (如果 s1[i] == s2[j])

如您所见,当前行元素仅取决于上一行的元素。

于 2014-02-27T14:04:33.007 回答
1

您的算法是正确的,但标准 DP 方法消除了您的第二阶段,并使解决方案更简单。

您可以在构建矩阵时计算对角线长度,而不是标记布尔值然后扫描对角线以查找最长序列 - 只需要一次通过。

就时间和空间复杂度而言,两种解决方案都是 O(NxM)。如果您使用位矩阵表示,您的解决方案可以节省一些内存,而其他解决方案可能会稍微快一些。

于 2014-02-27T15:05:17.803 回答