0.数组排序
public static int[] getTopK(int[] arr, int k) {
Arrays.sort(arr);
int left = 0, right = arr.length - 1;
while (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
return Arrays.copyOfRange(arr, 0, k);
// int[] topK = new int[k];
// for (int i = 0; i < k; i++) {
// topK[i] = arr[arr.length-1-i];
// }
// return topK;
}
public static void main(String[] args) {
int[] nums = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
int k = 4;
System.out.println(Arrays.toString(getTopK(nums, k)));
}
1.优先队列(最小堆)
public static int[] findTopK(int[] nums, int k) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
for (int num : nums) {
if (minHeap.size() < k) {
minHeap.offer(num);
} else if (num > minHeap.peek()) {
minHeap.poll();
minHeap.offer(num);
}
}
int[] topK = new int[k];
for (int i = k - 1; i >= 0; --i) {
topK[i] = minHeap.poll();
}
return topK;
}
public static void main(String[] args) {
int[] nums = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
int k = 4;
int[] topK = findTopK(nums, k);
System.out.println("Top " + k + " elements:");
for (int num : topK) {
System.out.print(num + " ");
}
}
输出结果:
2.Java8 stream排序
Arrays.stream(nums).boxed().sorted(Comparator.reverseOrder()).limit(4).collect(Collectors.toList())
总结:
(1).PriorityQueue
是基于堆(heap)实现的,它内部维持的是一个堆有序(heap-ordered)的二叉树。对于最小堆(Min-Heap),父节点总是小于或等于其子节点。因此,PriorityQueue
中的第一个元素(通过 peek()
或 poll()
获取的元素)总是队列中最小的元素。
(2).
Arrays.stream() 方法将基础类型数组转换为相应的原始类型流。
使用 boxed() 方法将原始类型流转换为 Stream<T>,以便进一步处理或收集结果。
(3).如果取最小的top-k,需要用最大堆
PriorityQueue
在 Java 默认是最小堆,通过自定义比较器 (a, b) -> b-a
将其转换为最大堆。这样可以确保堆顶元素是当前最大的元素。
PriorityQueue<Integer> minHeap = new PriorityQueue<>((a,b)->b-a);
......
if (minHeap.size() < k) {
minHeap.offer(num);
} else if (num < minHeap.peek()) {
minHeap.poll();
minHeap.offer(num);
}