我面临的问题是:
我有一个double
数组,我想从中保留最高k
个值。
Arrays.sort
的实现。例如,在this example中存在相对问题,建议使用此方法。k
元素感兴趣,因此我也尝试了MinMaxPriorityQueue
。我创建了MinMaxPriorityQueue
maximumSize
:当然还有自动装箱。
Builder<Comparable> builder = MinMaxPriorityQueue.maximumSize(maximumSize);
MinMaxPriorityQueue<Double> top2 = builder.create();
问题在于顺序是提升顺序,它与我想要的顺序相反。所以我不能这样用它。
要说明问题的真实参数,我的数组的长度约为50
个元素,我对顶级k = 5
元素感兴趣。
有没有办法绕过这个问题使用第二种方法?即使我真的不需要对所有元素进行排序,我应该留在第一个吗?你知道速度性能是否有任何显着差异(我将在很多情况下使用它,以便在需要速度的地方)?我可以使用其他任何解决方案吗?
至于表现,我知道理论上我可以自己检查一下,但我有点时间,如果有人有任何解决方案,我很高兴听到(或者无论如何阅读)。
答案 0 :(得分:3)
如果您只有50个元素,如我的评论所述,只需对其进行排序并选取最后k
个元素。它只有2行:
public static double[] largests(double[] arr, int k) {
Arrays.sort(arr);
return Arrays.copyOfRange(arr, arr.length - k, arr.length);
}
这会修改(排序)原始数组。如果您希望原始数组未经修改,则只需要+1行:
public static double[] largests2(double[] arr, int k) {
arr = Arrays.copyOf(arr, arr.length);
Arrays.sort(arr);
return Arrays.copyOfRange(arr, arr.length - k, arr.length);
}
答案 1 :(得分:0)
您可以在已排序的数组上使用System.arraycopy
:
double[] getMaxElements(double[] input, int k) {
double[] temp = Arrays.copyOf(input, input.length);
Arrays.sort(temp); // Sort a copy to keep input as it is since Arrays.sort works in-place.
return Arrays.copyOfRange(temp, temp.length - k, temp.length); // Fetch largest elements
}
对于50个元素,对数组进行排序要比乱用泛型和可比对象要快得多 我会写一个额外的&#34; fast&#34;算法...
double[] getMaxElements2(double[] input, int k) {
double[] res = new double[k];
for (int i = 0; i < k; i++) res[i] = Double.NEGATIVE_INFINITY; // Make them as small as possible.
for (int j = 0; j < input.length; j++) // Look at every element
if (res[0] < input[j]) { // Keep the current element
res[0] = input[j];
Arrays.sort(res); // Keep the lowest kept element at res[0]
}
return res;
}
这是O(N*k*log(k))
,而第一个是O(N*log(N))
。