这是一道面试题:
给定一个字符串,找出它的所有排列是字典中的一个单词。
我的解决方案:
将字典中的所有单词放入后缀树中,然后在树中搜索字符串的每个排列。
搜索时间是O(n)
,其中n
是字符串的大小。但是字符串可能有n!
排列。
如何提高效率?
这是一道面试题:
给定一个字符串,找出它的所有排列是字典中的一个单词。
我的解决方案:
将字典中的所有单词放入后缀树中,然后在树中搜索字符串的每个排列。
搜索时间是O(n)
,其中n
是字符串的大小。但是字符串可能有n!
排列。
如何提高效率?
你的一般方法还不错。
但是,您可以通过重新排列单词以使其所有字符按字母顺序排列,然后在字典中搜索,其中每个单词类似地重新排列为字母顺序并映射到原始单词,您可以避免搜索每个排列。
我意识到这可能有点难以理解,所以这里有一个例子。说你的话是飞跃。将其重新排列为aelp。
现在,在您的字典中,您可能会看到恳求和苍白这两个词。按照建议完成后,您的字典将(除其他外)包含以下映射:
...
aelp -> pale
aelp -> plea
...
所以现在,要找到你的字谜,你只需要找到aelp的条目(例如,使用建议的后缀树方法),而不是全部 4 个!= 24 种跳跃的排列。
一个快速的替代解决方案 - 完全取决于相关数据结构的大小。
如果字典相当小并且字符串相当长,您可以检查字典中的每个条目并确定它们是否是字符串的排列。你可以更聪明——你可以对字典进行排序并跳过某些条目。
为什么不使用哈希映射来存储字典单词?所以你得到 O(1) 的查找时间。如果你的输入是英文,你可以建立另一个表来告诉你字典中所有可能的字母,使用这个表,你可以在开头过滤一些输入。下面是一个例子:
result_list = empty;
for(char in input)
{
if(char not in letter_table)
{
return result_list;
}
}
for(entry in permutations of input)
{
if(entry in dictionary_hash_table)
{
result_list->add_entry();
}
}
return result_list
你应该把这些词放在一个尝试中。然后,您可以在生成排列时查找该单词。您可以跳过整个排列块,而第一部分不在 trie 中。
您可以构建从排序的字符列表到单词列表的映射。
例如,给定这些:
Array (him, hip, his, hit, hob, hoc, hod, hoe, hog, hon, hop, hos, hot)
你会在内部对它们进行排序:
Array (him, hip, his, hit, bho, cho, dho, eho, gho, hno, hop, hos, hot)
排序结果:
Array (bho, cho, dho, eho, gho, him, hip, his, hit, hno, hop, hos, hot)
在这个小样本中,我们没有匹配项,但是对于特定的单词,您可以在内部对其进行排序,并以此为关键字查看您的地图。
另一个简单的解决方案可能是下面的算法,
1) 使用“next_permutation”找到唯一的排列。
2) 使用“find/find_if”在字典中查找。