给定一个字符串数组,返回所有字符串组,即字谜。
我的解决方案:
对于数组中的每个字符串单词,将其排序为O(m lg m),m是单词的平均长度。
构建哈希表<字符串,列表>。
将排序后的单词作为键放入哈希表中,并生成单词的所有排列(O(m!)),用O(m)搜索字典中的每个排列(前缀树映射),如果是在字典中,将(O(1))放入哈希表中,以便将所有排列的单词放入具有相同键的列表中。
总的来说,O(n * m * lg m * m!)时间和O(n * m!)空间,n是给定数组的大小。
如果m非常大,则效率不高,m! 。
有更好的解决方案吗?
感谢
答案 0 :(得分:10)
我们定义一个字母表,其中包含我们的单词列表中可能包含的每个字母。接下来,我们需要为字母表中的每个字母使用不同的素数,我建议使用您能找到的最小字母。
这会给我们以下映射: {a => 2,b => 3,c => 5,d => 7,等等}
现在计算要表示为整数的单词中的字母,并按如下方式构建结果整数:
伪代码:
result = 1
for each letter:
....result *= power(prime[letter], count(letter,word)
一些例子:
aaaa => 2 ^ 4
aabb => 2 ^ 2 * 3 ^ 2 = bbaa = baba = ...
等等。
因此,您将有一个表示字典中每个单词的整数,并且您要检查的单词将能够转换为整数。因此,如果n是单词列表的大小,k是最长单词的大小,则需要O(nk)来构建新词典,使用O(k)来检查新单词。
Hackthissite.com有一个编程挑战:给定一个混乱的单词,在字典中查找它,看它是否在字典中有任何字谜。有一个good article解决问题的有效解决方案,我已经借用了答案,它还详细介绍了进一步的优化问题。
答案 1 :(得分:2)
使用计数排序对单词进行排序,以便可以在O(m)中进行排序。 排序后从word生成密钥并将节点(密钥,值)插入哈希表。生成密钥可以在O(m)中实现。
您可以将(键,值)中的值作为一个可以容纳多个字符串的动态数组。 每次插入已存在的键时,只需按下在数组上生成键的原始单词。
总体时间复杂度O(mn)其中n是单词总数(输入大小)。
此链接也解决了类似的问题 - > http://yourbitsandbytes.com/viewtopic.php?f=10&t=42
答案 2 :(得分:1)
#include <map>
#include <iostream>
#include <set>
#include <algorithm>
int main () {
std::string word;
std::map<std::string, std::set<std::string>> anagrams;
while(std::cin >> word) {
std::string sortedWord(word);
std::sort(sortedWord.begin(), sortedWord.end());
anagrams[sortedWord].insert(word);
}
for(auto& pair : anagrams) {
for(auto& word : pair.second) {
std::cout << word << " ";
}
std::cout << "\n";
}
}
我会让那些擅长大分析的人比我弄清楚复杂性。
答案 3 :(得分:1)
将字典转换为映射到这些字符的每个单词的单词的排序字符的映射并存储该字典。对于给出的每个单词,对其进行排序并将映射中的字谜列表添加到输出中。
答案 4 :(得分:0)
我不相信你能用O而不是
做得更好