我最近收到了一个关于SE角色的电话,并且被问到我如何判断两个单词是否是字谜,我给出了一个回复,其中涉及获取角色,迭代单词的内容,如果它存在退出循环等等。我认为这是一个N ^ 2解决方案,每个单词有一个循环,内部循环用于比较。
电话结束后我做了一些挖掘并写了一个新的解决方案;我计划明天在下一阶段的访谈中使用一个哈希映射,它使用一个哈希映射,其中唯一的素数代表字母表中的每个字符。 然后我循环遍历单词列表,计算单词的值并检查它是否与单词I&m; m check进行比较。如果值匹配,我们有一个胜利者(整个数学定理业务)。
这意味着一个循环而不是两个更好但是我开始怀疑自己,并且想知道散列图和乘法的附加操作是否比原始建议更昂贵。
我99%肯定哈希地图会更快但是......
任何人都可以证实或否认我的怀疑吗?谢谢。
编辑:我忘了提到我在考虑做任何事之前先检查单词的大小。
答案 0 :(得分:6)
anagram包含原始单词的所有字母,顺序不同。您在正确的轨道上使用HashMap
来处理线性时间内的单词,但您的素数概念是不必要的并发症。
您的数据结构是HashMap
,可以维护各种字母的数量。您可以在O(n)时间内添加第一个单词的字母。关键是字符,值是频率。如果该字母不在HashMap
,put
,则其值为1
。如果是,请将其替换为value + 1
。
当迭代第二个单词的字母时,从计数中减去一个,当它到达0
时删除一个字母。如果您尝试删除不存在的字母,则可以立即声明它不是字谜。如果你到达终点并且HashMap
不是空的,那么它不是一个字谜。否则,这是一个字谜。
或者,您可以用数组替换HashMap
。数组的索引对应于字符,值与以前相同。如果值降至-1
,则不是字谜,如果任何值不是0
,则结尾不是字谜。
你总是可以比较原始字符串的长度,如果它们不相同,那么它们就不可能是字谜。在开头包括此检查意味着您不必检查最后的所有值是否为0
。如果字符串的长度相同,那么任何一个都会生成-1
或者最后会有0
个。{/ p>
答案 1 :(得分:2)
乘法的问题是数字会变大。例如,如果是字母' c'是11,那么10 c的单词会溢出32位整数。
你可以将结果模数减去其他数字,但是你可能会产生误报。
如果你使用大整数,那么长篇大论就会慢慢来。
替代解决方案是对两个单词进行排序,然后比较相等性,或者使用chrylis在评论中建议的字母计数直方图。
我们的想法是将一个数组初始化为零,其中包含每个字母出现的次数。
浏览第一个单词中的字母,增加每个字母的计数。然后浏览第二个单词中的字母,减少计数。
如果在此过程结束时计数达到零,则单词为字谜。