剑指 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]限制:
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000
解题思路
最小k元素、最大k元素、中位数等问题都可以使用建堆来解决。
对于这道题中要求的最小k元素来说,我们建立一个大顶堆比建立一个小顶堆效率更高。因为如果我们不需要每个元素顺序输出的话,建立小顶堆,只需要保证小顶堆中的元素是k个,并且遍历arr数组中的元素,出现比堆顶元素小的元素就进行替换。
遍历完成之后,大顶堆中的元素个数就是k个,遍历结果输出即可。
Java代码
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
int [] res = new int [k];
if(arr.length<k || k==0) return res;
Queue<Integer> q = new PriorityQueue<>((o1,o2)->o2-o1);
for(int i=0;i<arr.length;i++){
if(q.size()<k) q.offer(arr[i]);
else if(arr[i]<q.peek()){
q.poll();
q.offer(arr[i]);
}
}
int ind = 0;
while(!q.isEmpty()){
res[ind++] = q.poll();
}
return res;
}
}