鉴于2个字符串A
和B
,您必须在两个操作中将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)
解决方案,但我被告知有更好的解决方案。
答案 0 :(得分:2)
我认为我得到了O(n)
解决方案。它分几步完成。
首先,让我们重新解决问题。我们必须从A
中删除一个子字符串,从B
中删除一个子字符串,以便剩下的内容相等。我们希望尽可能从A
删除短子串。请注意,您的插入操作实际上等同于B
上的相同删除操作。
引理。如果您从A
和B
中删除相同的前缀或后缀,则不会影响最佳解决方案。向读者留下证据:)
现在,提取A
和B
的最大公共后缀和前缀,A=XA*Y
,B=XB*Y
,其中X
和Y
是子串。如果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}}。这里B
,a1 != b1
。
要使a2 != b2
和A
相等,我们必须从其中一个字符串中删除第一个符号,从另一个字符串中删除最后一个符号。你有两个案例。我们只考虑一个,您从B
删除第一个符号,从A
删除最后一个符号。
现在你所要做的就是从B
的开头删除尽可能少的符号,这样左边的后缀将等于A
的某个前缀。为此,您应构造suffix tree字符串B
并浏览A
的所有前缀,以检查它们是否以后缀树形式显示。选择最大的。完成后,您将拥有最大字符串B
,后缀为C
,前缀为A
:
B
从A = PC
B = CS
移除P
,从A
移除S
,您就完成了。
对于原始B
和A
(不删除常用部分),我们有:
B
在问题的原始表述中,A = XPCY
B = XCSY
被删除,并插入了P
。
后缀树可以在S
中构建。在第一步中剥离gretest公共后缀和前缀需要O(n)
。后缀树遍历在O(n)
中完成。