使用素数比循环更快地确定字谜?

Using primes to determine anagrams faster than looping through?

我最近有一个 SE 角色的电话,有人问我如何确定两个词是否是变位词,我给出的回答涉及获取字符、迭代单词、如果它存在退出循环等等。我认为这是一个 N^2 解决方案,每个单词一个循环,内部循环用于比较。

通话结束后,我进行了一些挖掘并编写了一个新的解决方案;我计划明天在下一阶段面试时交出的一个,它使用哈希图,其中包含代表字母表中每个字符的唯一质数。 然后我循环遍历单词列表,计算单词的值并检查它是否与我正在检查的单词进行比较。如果值匹配,我们就有赢家(整个数学定理业务)。

这意味着一个循环而不是两个循环要好得多,但我开始怀疑自己并想知道哈希图和乘法的额外操作是否比最初的建议更昂贵。

我 99% 确定哈希映射会更快但是...

谁能证实或否认我的怀疑?谢谢。

编辑:我忘了说我在考虑做任何事情之前都会先检查单词的大小。

乘法的问题是数字会变大。例如,如果字母 'c' 是 11,那么具有 10 个 c 的单词将溢出 32 位整数。

您可以将结果以其他数字为模减少,但这样会有误报的风险。

如果你使用大整数,那么对于长词来说它会变慢。

替代解决方案是对两个词进行排序,然后比较是否相等,或者使用评论中 chrylis 所建议的字母计数直方图。

我们的想法是将一个数组初始化为零,其中包含每个字母出现的次数。

遍历第一个单词中的字母,增加每个字母的计数。然后遍历第二个单词中的字母,递减计数。

如果在此过程结束时计数达到零,则这些词是变位词。

一个字谜包含原始单词的所有字母,顺序不同。您使用 HashMap 在线性时间内处理单词是正确的,但您的素数想法是不必要的复杂化。

您的数据结构是一个 HashMap,用于维护各种字母的计数。您可以在 O(n) 时间内从第一个单词添加字母。键是字符,值是频率。如果字母不在 HashMap 中,put 它的值为 1。如果是,请将其替换为 value + 1.

当遍历第二个单词的字母时,从你的计数中减去一个,当它达到0时删除一个字母。如果您尝试删除一个不存在的字母,那么您可以立即声明它不是字谜。如果你到达终点并且 HashMap 不为空,则它不是字谜。否则,它是一个字谜。

或者,您可以用数组替换 HashMap。数组的索引对应字符,取值和之前一样。如果一个值下降到 -1,它就不是一个变位词,如果任何值不是 0.

,它最后也不是一个变位词

您始终可以比较原始字符串的长度,如果它们不相同,则它们不可能是变位词。在开头包括此检查意味着您不必在末尾检查所有值是否为 0。如果字符串的长度相同,那么要么会产生一个 -1,要么最后会有所有的 0