在给定的int序列中计算双重回文

时间:2010-06-09 20:11:18

标签: algorithm palindrome

对于给定的int序列,检查双回文的数量,其中双回文是指两个相同的回文序列,它们之间没有断裂。例如:

in 1 0 1 1 0 1我们有1 0 1作为回文,出现2次不间断,

in 1 0 1 5 1 0 1我们有1 0 1但它是分开的

(除了这些序列中的其他回文)

问题示例测试数据是:

  

3

     

12 0 1 1 0 0 1 1 0 0 1 1 0

     

12 1 0 1 0 1 0 1 0 1 0 1 0

     

6 3 3 3 3 3 3

带答案

  

8 0 9

Manacher对于乞讨是显而易见的,但我不知道接下来该做什么。任何想法都赞赏。复杂度应低于n ^ 2我猜。

编辑:int在此被视为字母的单个元素

2 个答案:

答案 0 :(得分:0)

我将从2个集合开始:

  • “成长”序列的集合
  • '收缩'序列的集合

算法的工作原理如下:

  • 最初两个集合都是空的
  • 逐个处理向量的值,假设我们现在正在查看值V
  • 循环所有'成长'序列
    • 如果生长序列的最后一个值等于V,则将生长序列复制到收缩序列集合中,从新收缩序列的末尾删除V
    • 如果生长序列的一个但最后一个值等于V,则将生长序列复制到收缩序列的集合,从收缩序列中删除最后两个元素(V和最后一个)
  • 循环所有'收缩'序列
    • 如果收缩序列的最后一个值等于V,则将其从收缩序列中移除。如果收缩序列变空,我们找到了回文。
    • 如果收缩序列的最后一个值不等于V,则删除此收缩序列
  • 最后制作一个新的增长序列,仅由V
  • 组成

事实上,生长序列是一次可能成为回文序列的序列,而收缩序列则是“部分”回文序列。

答案 1 :(得分:0)

由于您已经知道找到所有回文的算法(BTW非常棒),您需要做的就是以下几点。请注意,“双回文”也是回文:
反向(PP)=反向(P)反向(P)= PP。

所有回文(a,b)中找到((a,b)我指的是从a位置到b位置的回文),你需要找到(i,j,k) } (i,j)(j,k)(i,k)都是回文,j-i=k-j。同样,对于您找到的每个回文(i,j),您只需设置k = 2j-i,并检查(k,j)(i,k)是否为回文。

如果第一步总共返回M个回文,则需要O(M)时间(假设你存储它们以便检查是否存在回文是O(1)),所以O(n 2 )在最坏的情况下。我认为在最坏的情况下这应该是最佳的(考虑所有1的字符串)。