如何创建一个新数组,包含在java中最多出现k次的所有数组?
例如,如果数组是:
{1,4,4,3,4,3,5,2,5,1,5}
和k = 2
,新数组将是:
{1,3,2}.
我假设我需要比较数组中的元素并添加存储它作为变量出现的次数。然后我将该变量与k
进行比较,如果它小于或等于它,它会将它添加到一个新的arraylist。我无法真正实现这一点。
感谢
答案 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)
至少有两种方法可以做到:
第一个是时间最优的,第二个是空间最优的。