题目
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
提示:
0 <= len(arr) <= 100000
0 <= k <= min(100000, len(arr))
思路
使用JDK内置的优先级队列(基于最小堆)。
取小用大,构建最大堆。
代码
class Solution {
public int[] smallestK(int[] arr, int k) {
int[] ret = new int[k];
//边界
if(arr.length == 0 || k == 0) {
return ret;
}
//构建一个最大堆
//JDK的优先级队列是最小堆,如何让把最小堆变为最大堆?用到比较器!
Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
//创建queue的时候是在构造函数里覆写了接口
//匿名内部类,类的内部实现了Comparator接口,然后把它作为参数传到这个构造方法中
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1; //默认是o1 - o2,这里把它倒过来,将JDK原先的最小堆改造为最大堆
}
});
//遍历原数组,将元素加入最大堆
for (int value : arr) {
if(queue.size() < k) {
queue.offer(value);
} else {
if(value < queue.peek()) {
queue.poll();
queue.offer(value);
}
}
}
//当扫描完整个数组时,queue中就存储了前k小个元素,依次出队即可
for (int i = 0; i < k; i++) {
ret[i] = queue.poll();
}
return ret;
}
}