剑指 Offer 40. 最小的k个数
说明
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例
示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
示例2:
输入:arr = [0,1,2,1], k = 1
输出:[0]
题解思路
令堆的大小为k,遍历数组:
1.如果当前堆的大小小于k,直接将该数字放入堆中
2.否则,如何该数字小于堆顶元素的值,则将堆顶元素替换为该数字
3.如果该数字大于堆顶元素的值,直接跳过
解题时遇到的问题
PriorityQueue是小根堆(堆顶是最小的值),此题需要替换的是堆里面最大的值,所以不符合条件
解决方案:借助comparator比较器,来实现大根堆。
示例:Queue q = new PriorityQueue(new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return o2.compareTo(o1);
}
});
解决问题查阅的资料
代码实现
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
Queue<Integer> q = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return o2.compareTo(o1);
}
});
if (k == 0 || arr.length == 0) {
return new int[0];
}
for(int i :arr){
if(q.size() < k){
q.add(i);
}else {
if(i < q.peek()){
q.poll();
q.add(i);
}
}
}
int[] result = new int[k];
int index = 0;
for(int j : q){
result[index] = j;
index++;
}
return result;
}
}