查找数组中出现奇数次数的所有元素

时间:2013-11-05 17:26:24

标签: arrays algorithm search data-structures hashmap

我遇到了以下问题:

'查找数组中出现奇数次的所有元素'。

我对此的看法是:

  1. 使用HashMap:在数组中添加值作为HashMap中的键。与每个键对应的值将是遇到键的次数。

  2. 使用O(N log N)中的快速排序对数组进行排序,然后遍历数组以检查哪些元素出现奇数次。

  3. 您如何看待,还有其他方法吗?如果不是,那么这两种方法中的哪一种更好?

    提前致谢!

3 个答案:

答案 0 :(得分:15)

您可以修改第一种方法来使用哈希集而不是哈希映射。

创建一个最初为空的哈希集。浏览数组的元素。对于每个元素,检查哈希集:如果当前数组元素不在集合中,则添加它;否则,将其删除。

当你到达数组的末尾时,你的哈希集将包含你的数组中出现奇数次的每个对象。

由于访问哈希集中的元素为O(1),因此该算法的时间复杂度为O(N)

答案 1 :(得分:5)

“更好”取决于背景。使用散列映射或散列集会更快,并且具有不修改原始数组的优点,但它需要额外的O(N)内存。排序和计数需要更长时间并修改数组,但不需要额外的内存。

您选择哪种解决方案取决于您是否能够承受额外的内存。

答案 2 :(得分:0)

基本上这可以作为重新平衡效率的练习来完成:您浏览数字列表,对于您在集合中已有的每个数字,您可以再次删除它。这样你的比较集大约是可能最大值的一半。当然,这不会改变O(n lg n),并且每个步骤都会得到一个分配/解除分配,这可能会更加昂贵。

因此使用混合策略可能会很有趣:quicksort非常快,但是你基本上想要在它们相等时合并两个条目,并且至少(n-1)/ 2个条目是相等的。 Quicksort在排序时并不能真正适应元素的删除。

因此,采用基于数组的方法(降低分配成本),我宁愿使用一些基于堆的方法。每当你碰到相同的元素时,你就删除一个。堆排序与快速排序相当具有竞争力,并且能够提前修剪树将会变得有用。