如何输出一个新数组,包含最多出现k次的前一个数组的所有数字

时间:2011-09-12 18:21:12

标签: java arrays algorithm

如何创建一个新数组,包含在java中最多出现k次的所有数组?

例如,如果数组是:

{1,4,4,3,4,3,5,2,5,1,5}

k = 2,新数组将是:

{1,3,2}.

我假设我需要比较数组中的元素并添加存储它作为变量出现的次数。然后我将该变量与k进行比较,如果它小于或等于它,它会将它添加到一个新的arraylist。我无法真正实现这一点。 感谢

2 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点,具体取决于你的约束条件。

如果您不需要担心内存限制,可以使用从数组元素映射到其频率的HashMap来轻松解决此问题。该算法可以通过扫描整个阵列来工作。对于每个元素,如果该元素已经在HashMap中,则更新HashMap中的键/值对以增加该元素的频率。否则,如果未看到该元素,则将频率更新为1.完成填充HashMap后,您可以遍历地图并复制所有频率最高的元素{ {1}}转换为新的k。例如:

ArrayList

这在O(n)时间和O(n)内存中运行,这非常好。

如果您不想将所有内容存储在内存中,则另一个选项是使用for(Map.Entry<T, Integer> entry: myMap.entrySet()) { if (entry.getValue() <= k) myArrayList.add(entry.getKey()); } 在O(n log n)时间和O(log n)空间中对数组进行排序。对阵列进行排序后,每个值的所有副本将连续存储,您可以更轻松地计算其频率。例如,在对原始帖子中提到的数组进行排序后,您将得到数组

Arrays.sort

从这里开始,确定每个元素的副本应该更容易。您可以通过遍历数组,跟踪您当前正在查找的元素以及有多少副本来完成此操作。每当看到一个新元素时,如果它与当前元素匹配,则递增计数器。如果没有,则将要检查的元素重置为新元素,并将计数器设置为1。例如,使用上面的数组,您可以从查看此元素开始:

1 1 2 3 3 4 4 4 5 5 5

现在,您查看数组的下一个元素。因为它是1,所以将频率计数增加到2:

1 1 2 3 3 4 4 4 5 5 5
^

Element: 1
Frequency: 1

当你看下一个元素时,你会发现它是一个2.这意味着剩下的还有1个。因为有两个副本1,所以您可以将1附加到结果数组。然后,您将计数器重置为1,保持此状态:

1 1 2 3 3 4 4 4 5 5 5
  ^

Element: 1
Frequency: 2

执行此操作时要注意的一件事是记住处理访问最终数组元素的情况。重要的是,当您点击数组的末尾时,如果您最后一个元素的1 1 2 3 3 4 4 4 5 5 5 ^ Element: 2 Frequency: 1 个副本,则将最后一个数字添加到输出数组中。

每当执行此操作时,如果您发现最多出现k次的元素,则可以将其添加到新数组中。第二步在O(n)时间和O(m)空间中运行(其中m是结果数组中元素的总数),因此总复杂度为O(n log n)时间和O(m + log n)空间。

希望这有帮助!

答案 1 :(得分:1)

至少有两种方法可以做到:

  1. 线性扫描数组,更新存储每个遇到数字频率的哈希表(平均时间:O(n),空格:O(n));
  2. 对数组进行排序并保持计算当前元素的次数(每次当前数字与前一个元素不同时将设置为1)。时间:O(n lg n),空格:O(m),其中m是返回元素的数量(假设使用O(1)空间复杂度分类器,如heapsort)。
  3. 第一个是时间最优的,第二个是空间最优的。