从单词列表中构造回文
Constructing palindrome from a list of words
最近我在看一些面试问题,发现了一些有趣的问题:
给你一个单词列表。找出两个单词是否可以连接起来形成一个回文。考虑一个列表{bat, tab, cat},然后bat和tab可以连接起来形成一个回文。期望一个O(nk)的解决方案,其中n =作品数,k为长度
可以有多个对,如果找到就返回true。
另外,在评论中,其中一种方法是:
1)将第一个单词添加到树(A B)
2)取第二个单词(D E E D B A),倒写(A B D E E D)
3)看你能在字母表中匹配多少个倒过来的字母(前2个)
4)取字符串的其余部分(D E E D),看看它是否是回文,如果是,则返回true
5)将第二个单词添加到三(D E E D B A)
6)用下一个单词
返回步骤27)当缺字时返回false
但在我看来,这不是一个0 (nk)的解决方案。
谁能提出一个解决方案?或者解释一下为什么上面描述的算法是O(nk)??算法是正确的,或者至少非常接近。有一些小的技术问题。在步骤4中。如果一个解决方案比当前方案更好,那么在步骤7中应该保存这个方案。返回它,或者说不可能生成回文
主要思想是将单词处理成核和前缀。如果核心是回文,那么我们需要用其他单词匹配前缀。Trie作为处理过的字符串的"数据库",因此对于每个新单词,可以检查所有可能的扩展。如果单词单独保存,则需要分别比较每个单词的前缀。
(编辑:我认为仍然存在一个小漏洞,以防在一个字符串中有两个开头相同的单词,而进入的单词将与较短的单词组成回文,而不是较长的单词,但我不会详细说明。处理它会使算法复杂化,但不会影响复杂度。)
也为O(n*k)
。添加和检查前缀与trie所需的步数与字符数成正比。在这种情况下,它是由k
束缚的。就像树的操作是O(h)
,其中h
是树的高度。所以总结一下:
-
k
steps. -
采取
k
步骤 -
也最多执行
k
步。 -
也比
k
的步骤少,但我们可以通过k
来约束它。 -
也执行
k
步骤
步骤2至步骤5重复n-1
次。
当然,每一步都有不同的主导操作,所以很难指定确切的常数,但它们都受k
的约束,所以复杂度是O(c*(n-1)*k)
,本质上是O(n*k)
。
Dobbs博士在2004年的一篇文章中对此进行了非常有趣的讨论。完整的解释有点长,但大意是:
假设您从Lion开始,其中枢轴位于实际单词的左侧。我可以计算弦的中心,也就是位置2。枢轴是零,所以字符串在右边太重了,但目前,Lion符合部分回文的条件。轴心点上的"点"与轴心点上的点相匹配,因此至少有一个正确的字符,尽管是相同的字符。现在,您希望在以noil结尾的单词前添加前缀,并尝试将字符串转换为noil. lion。我指的是任何字符串。如果您成功了,那么您需要定位以开头的单词,以便将它们添加到字符串中。
注意,他将部分回文定义为:
如果从枢轴点向外工作,在不匹配发生之前遇到字符串的左端或右端,则字符串是部分回文。
- C++:正在检查LinkedList中的回文-递归方法-错误
- Usaco第1.6节主要回文
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 将 S1 转换为回文,并将 S2 作为其子字符串
- 数回文词
- 最长的回文子串(C++帮助)
- 有人可以详细解释这个回文代码是如何工作的吗?
- 回文递归版本
- 如何检查C ++ STL列表是否为回文?
- 回文数在 1 到 10000 之间
- C++ - 检查结构数据类型中的单词是否为回文
- 是回文作业练习
- 回文递归不停止
- 整数数组中最长的回文
- 回文测试
- 是否可以检查存储在堆栈上的单词是否是回文,而C++中没有任何附加数据结构
- 我试图编写一个代码来查找一个单词是否是回文,但它不起作用。怎么了?
- 内联程序集 - 检查单词是否为回文
- 需要修改堆栈/链表程序以确定单词是否为回文
- 从单词列表中构造回文