从单词列表构造回文

时间:2015-05-17 21:39:14

标签: c++ algorithm search palindrome

最近我正在浏览一些面试问题,并发现了一些有趣的问题:

您将获得一个单词列表。找出两个单词是否可以连接 - 聚集形成回文。例如,考虑一个列表{bat,tab,cat}然后可以将bat和tab连接起来形成一个回文。 期待一个O(nk)解决方案,其中n =工作数,k是长度

可以有多对,只要找到它就返回true。

此外,在评论中,其中一种方法是:

1)将第一个单词添加到trie(A B)
2)取第二个字(D E E D B A)并将其反转(A B D E E D)
3)查看在trie中可以匹配的反向字中有多少个字母(前2个)
4)取其余的绳子(D E E D)看它是否是回文如果是你完成则返回true 5)将第二个单词添加到trie(D E E D B A)
6)用下一个单词回到步骤2 7)当单词返回false时

但在我看来,这不是O(nk)解决方案。

有人可以提出解决方案吗?或者解释为什么上述算法是O(nk)??

2 个答案:

答案 0 :(得分:2)

算法是正确的,或者至少它非常接近。有一些小技术问题。在第4步中,如果解决方案比当前解决方案更好,那么应该保存解决方案的命题,并且在步骤7中,应该保留解决方案的命题,或者说它不可能成为回文。

主要思想是将单词处理为核心和前缀。如果核心是回文,那么我们需要将前缀与其他单词匹配。 Trie是一个数据库"对于已处理的字符串,因此对于每个新单词,可以检查所有可能的扩展名。如果单词保持单独,则需要分别比较每个单词的前缀。

编辑:我认为仍然存在一个小漏洞,如果一个trie中有两个单词开始相同,并且即将进入的单词会与较短的单词形成回文,但不会更长,但我不会详细说明。处理它会使算法复杂化,但不会影响复杂性。

它也是O(n*k)。添加和检查前缀vs trie需要与字符数成比例的步数。所以在这种情况下,它受k的约束。就像树操作O(h)一样,其中h是树的高度。总之:

  1. k步骤。

  2. 需要k步。

  3. 最多只需k步。

  4. 也需要少于k个步骤,但我们可以k限制它。

  5. 也需要k步。

  6. 步骤2到5完成n-1次。

    当然每个步骤都有不同的显性操作,因此很难指定确切的常量,但所有这些都被k约束,因此复杂度为O(c*(n-1)*k),基本上为{{1} }}

答案 1 :(得分:0)

2004年,Dr. Dobbs的一篇文章对此进行了非常有趣的讨论。完整的解释有点长,但总体思路是:

  

假设您从Lion开始,其中枢轴是实际单词的左侧。我可以计算出弦的中心,即位置2。枢轴为零,因此右侧的弦太重,但此刻,Lion有资格作为部分回文。枢轴点处的“点”与枢轴点处的点匹配,因此至少有一个正确的字符,尽管是相同的字符。您现在希望添加以落棉结尾的单词,尝试将字符串转换为noil.Lion。我用来表示任何字符串。如果您成功了,那么您需要找到以字母开头的单词,以便将它们附加到字符串中。

请注意,他将部分回文定义为:

  

如果从枢轴点向外工作,字符串是部分回文,则在发生不匹配之前遇到字符串的左端或右端。