思路
直接排序的话时间复杂度是O(nlogn)。
建大顶堆,一开始先将k个元素入堆。
然后后面每个元素都和堆顶元素比较,如果堆顶大于该元素,就让堆顶元素出堆,让该元素入堆。
时间复杂度是(nlogk)。
代码
class Solution {
public int[] smallestK(int[] arr, int k) {
PriorityQueue<Integer> heap = new PriorityQueue<>((a,b)->{return b-a;});
for(int i=0;i<arr.length;i++){
if(heap.size() < k) heap.offer(arr[i]);
else{
if(!heap.isEmpty() && heap.peek() > arr[i]){
heap.poll();
heap.offer(arr[i]);
}
}
}
int[] res = new int[k];
for(int i=0;i<k;i++){
res[i] = heap.poll();
}
return res;
}
}
Java堆的使用
堆(heap)是一种满足特定条件的完全二叉树。
大顶堆 max heap:任意节点的值>=其子节点的值。堆顶元素最大。
小顶堆 min heap:任意节点的值<=其子节点的值。堆顶元素最小。
Java 的 PriorityQueue 的底层是堆。我们可以将其看做堆来使用。
// 默认为小顶堆
Queue<Integer> minHeap = new PriorityQueue<>();
// 初始化大顶堆
Queue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
常用函数:
- offer(E e) 元素入堆
- peek() 返回堆顶元素
- poll() 堆顶元素出堆
参考:
https://blog.csdn.net/xd__xy/article/details/135265924?fromshare=blogdetail&sharetype=blogdetail&sharerId=135265924&sharerefer=PC&sharesource=weixin_61026052&sharefrom=from_link