通过仅在字符串末尾添加字符来扩展到最短回文的算法

时间:2013-08-03 15:06:58

标签: c++ algorithm

我发现了一个算法问题。我解决了这个问题,但我想优化它。我在这里问同样的问题。

问题

给出一个字符串,该字符串的长度为 N <= 10000000 。该字符串的所有字符都来自'a'到'z'。现在我们必须通过在末尾添加字符来计算我们可以从给定字符串中创建的最小回文。

示例

给定String ='abab'

输出='ababa'

推理:字符串ababa包含从字符串开头和结尾开始的字符串abab,每端只有一个额外的字符。

被修改

String ='abbcd' 输出='abbcdcbba'

我的尝试

我可以用O(N ^ 2)复杂度来解决这个问题。

我的问题

我可以在不到O(N ^ 2)的时间内解决这个问题吗? ,如果是,那么算法是什么? (给我一个提示)

2 个答案:

答案 0 :(得分:3)

请注意,在回文结构中,与字符串中间距离相等的所有字符对都是相等的。

这表明以下算法:

  

找到最大的回文后缀,然后在该回文后缀的左侧附加子串的反向。这将通过在字符串的末尾添加字符来获得可获得的最短回文。

对此的粗暴实现将是O(n^2)。您可以使用两个rolling hashesO(n)来测试后缀是O(1)中的回文。

以下是这些哈希工作原理的概述:

hForward(suff)  = suff[0] * p^0 + suff[1] * p^1 + ... + suff[k] * p^k
hBackward(suff) = suff[k] * p^0 + suff[k-1] * p^1 + ... + suff[0] * p^k

When adding a new character to the suffix:
Note that this is added to the beginning, since we should iterate the suffixes
from right to left.
hForward(c + suff) = c * p^0 + p * hForward(suff)
hBackward(c + suff) = hBackward(suff) + c * p^(k + 1)  

p可能应该是一个(小的)素数,你应该做所有的计算mod另一个(大型)素数。为了保持高效,请逐步计算功率,不要使用任何取幂算法。你可以使用更多的哈希来避免误报。

如果我没有混淆事情,还有一个涉及KMP algorithm的解决方案,但我不再熟悉它了。

答案 1 :(得分:0)

直接的θ(n)方法(对于n字符输入字符串S)是在θ(n)时间内为S建立suffix tree T。设R =反向(S)。在时间O(n)中,使用T在S的后缀中找到R的最长匹配。假设最长匹配具有m个字符;即,R的前m个字符与S的最后m个匹配,m是最大的。设P是R的最后n-m个字符,或者是S的第一个n-m的反转。期望的结果是S + P.