我遇到了以下问题:
'查找数组中出现奇数次的所有元素'。
我对此的看法是:
使用HashMap
:在数组中添加值作为HashMap中的键。与每个键对应的值将是遇到键的次数。
使用O(N log N)中的快速排序对数组进行排序,然后遍历数组以检查哪些元素出现奇数次。
您如何看待,还有其他方法吗?如果不是,那么这两种方法中的哪一种更好?
提前致谢!
答案 0 :(得分:15)
您可以修改第一种方法来使用哈希集而不是哈希映射。
创建一个最初为空的哈希集。浏览数组的元素。对于每个元素,检查哈希集:如果当前数组元素不在集合中,则添加它;否则,将其删除。
当你到达数组的末尾时,你的哈希集将包含你的数组中出现奇数次的每个对象。
由于访问哈希集中的元素为O(1)
,因此该算法的时间复杂度为O(N)
。
答案 1 :(得分:5)
“更好”取决于背景。使用散列映射或散列集会更快,并且具有不修改原始数组的优点,但它需要额外的O(N)内存。排序和计数需要更长时间并修改数组,但不需要额外的内存。
您选择哪种解决方案取决于您是否能够承受额外的内存。
答案 2 :(得分:0)
基本上这可以作为重新平衡效率的练习来完成:您浏览数字列表,对于您在集合中已有的每个数字,您可以再次删除它。这样你的比较集大约是可能最大值的一半。当然,这不会改变O(n lg n),并且每个步骤都会得到一个分配/解除分配,这可能会更加昂贵。
因此使用混合策略可能会很有趣:quicksort非常快,但是你基本上想要在它们相等时合并两个条目,并且至少(n-1)/ 2个条目是相等的。 Quicksort在排序时并不能真正适应元素的删除。
因此,采用基于数组的方法(降低分配成本),我宁愿使用一些基于堆的方法。每当你碰到相同的元素时,你就删除一个。堆排序与快速排序相当具有竞争力,并且能够提前修剪树将会变得有用。