将字符串a转换为字符串b

时间:2013-04-01 05:48:07

标签: string algorithm optimization data-structures

鉴于2个字符串AB,您必须在两个操作中将A转换为B

  • delete(i, len):从i A开始删除len chars(您可以删除无字符)
  • insert(i, str):在A i处插入一个字符串str - 索引(可以插入一个空字符串)

您必须尽量减少删除操作删除的字符数。

约束:

  • 插入只能在删除
  • 后应用
  • 删除和插入只能应用一次

例1:

A = aabcdef  
B = aaefg

答案:delete(2, 3); insert(4, "g")。总而言之,删除了3个字符,这是我们能做的最好的事情。

示例2:

A = aaaaa  
B = a

我们只需要删除4个字符

我想到了O(n^3)O(n^2)解决方案,但我被告知有更好的解决方案。

1 个答案:

答案 0 :(得分:2)

我认为我得到了O(n)解决方案。它分几步完成。

首先,让我们重新解决问题。我们必须从A中删除一个子字符串,从B中删除一个子字符串,以便剩下的内容相等。我们希望尽可能从A删除短子串。请注意,您的插入操作实际上等同于B上的相同删除操作。

引理。如果您从AB中删除相同的前缀或后缀,则不会影响最佳解决方案。向读者留下证据:)

现在,提取AB的最大公共后缀和前缀,A=XA*YB=XB*Y,其中XY是子串。如果A*B*为空,我们会得到一个简单的退化情况。如果没有,请让我们制作新的符号A<-A*B<-B*

此时first(A) != first(B)last(A) != last(B)。否则,我们应该在前一步骤中包含一个通用符号作为前缀或后缀:

A = a1 A' a2
B = b1 B' b2

其中a1 = first(A)a2 = last(A)b1 = first(B)b2 = last(B)以及A'B'A和{{的子字符串1}}。这里Ba1 != b1

要使a2 != b2A相等,我们必须从其中一个字符串中删除第一个符号,从另一个字符串中删除最后一个符号。你有两个案例。我们只考虑一个,您从B删除第一个符号,从A删除最后一个符号。

现在你所要做的就是从B的开头删除尽可能少的符号,这样左边的后缀将等于A的某个前缀。为此,您应构造suffix tree字符串B并浏览A的所有前缀,以检查它们是否以后缀树形式显示。选择最大的。完成后,您将拥有最大字符串B,后缀为C,前缀为A

B

A = PC B = CS 移除P,从A移除S,您就完成了。

对于原始BA(不删除常用部分),我们有:

B

在问题的原始表述中,A = XPCY B = XCSY 被删除,并插入了P

后缀树可以在S中构建。在第一步中剥离gretest公共后缀和前缀需要O(n)。后缀树遍历在O(n)中完成。