给定一个字符串数组,返回所有的字谜字符串组
Posted
技术标签:
【中文标题】给定一个字符串数组,返回所有的字谜字符串组【英文标题】:Given a string array, return all groups of strings that are anagrams 【发布时间】:2012-01-22 06:15:20 【问题描述】:。
我的解决方案:
对数组中的每个字符串单词,排序O(m lg m),m是单词的平均长度。
建立一个哈希表
将排序好的单词作为key放入哈希表,同时生成单词的所有排列(O(m!)),用O(m)在字典(前缀树映射)中搜索每个排列,如果是在字典中,将它(O(1))放入哈希表中,以便所有排列后的单词都放入具有相同键的列表中。
总共 O(n * m * lg m * m!) 时间和 O(n* m!) 空间,n 是给定数组的大小。
如果 m 很大,则效率不高,m! .
有更好的解决方案吗?
谢谢
【问题讨论】:
【参考方案1】:我们定义了一个字母表,其中包含我们单词表中可能存在的每个字母。接下来,我们需要为字母表中的每个字母使用不同的质数,我建议使用你能找到的最小的。
这将为我们提供以下映射: 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 是我借用答案的问题的有效解决方案,它还详细介绍了进一步的优化。
【讨论】:
我们还应该考虑构建字母 O(sizeof(dictionary) * k) 的成本。在您的解决方案中, O(nk) 用于给定的字符串数组而不是字典。谢谢 是的,我应该在那里更清楚,n 是字典的大小,给定的字符串数组可能是 l,然后一旦字典建成,运行时间就会 O(lk) 这是一个疯狂的解决方案。使用您的方案,“pizza”一词的值大于 9.6 e19。您的值会经常超出 64 位数字的范围,并且有些英文单词会超出 128 位数字的范围。你最好使用字符串键。【参考方案2】:使用计数排序对单词进行排序,以便在 O(m) 中完成排序。 排序后从单词生成键并将节点(键,值)插入哈希表。生成密钥可以在 O(m) 内完成。
您可以将 (key,value) 中的值作为可以容纳多个字符串的动态数组。 每次插入一个已经存在的键时,只需将生成键的原始单词推送到值数组上。
所以总体时间复杂度为 O(mn),其中 n 是单词的总数(输入的大小)。
此链接也有解决类似问题的方法-> http://yourbitsandbytes.com/viewtopic.php?f=10&t=42
【讨论】:
【参考方案3】:#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";
我会让比我更擅长大 O 分析的人弄清楚其中的复杂性。
【讨论】:
m - 任何字符串中的最大字符数,n - 字符串总数。 m * log m 用于对每个字符串进行排序。 m * log n 用于插入anagrams
。 m 因子,因为每个字符串比较都需要 O(m) 时间。因此,O(n * m * (log n + log m)) 是一个上限。【参考方案4】:
将字典转换为一个单词的排序字符的映射,映射到这些字符的每个单词并存储它。对于给定的每个单词,对其进行排序并将映射中的字谜列表添加到您的输出中。
【讨论】:
【参考方案5】:我不相信你可以在 O 方面做得比
对每个单词的字母进行排序 对已排序的单词列表进行排序 现在将连续分组每组字谜。【讨论】:
以上是关于给定一个字符串数组,返回所有的字谜字符串组的主要内容,如果未能解决你的问题,请参考以下文章