面试题 17.14. 最小K个数(排序+堆)

1. 题目

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

2. 示例

输入: arr = [1,3,5,7,2,4,6,8], k = 4

输出: [1,2,3,4]

3. 提示

  • 0 <= len(arr) <= 100000

  • 0 <= k <= min(100000, len(arr))

4. 题解

本题有两种方式实现

1、排序:最小到最大排序,然后取钱k个,时间复杂度O(nlogn)、空间复杂度O(logn)

2、堆:因为最大堆实时维护数组的前K小值。首先将前k个数插入大根堆,然后从K+1个数开始遍历,比较堆顶元素与第k+1个数。若小,不变;若大,先出堆顶元素放入第k+1元素。时间复杂度O(nlogk)、空间复杂度O(k)。

5. Code

 1 public int[] smallestKA(int[] arr, int k) {
 2         /**
 3          * @Method: smallestKA
 4          * @Author: haifwu
 5          * @Version:  1.0
 6          * @Date: 28/05/2021 12:05
 7          * @param arr
 8          * @param k
 9          * @Return: int[]
10          * @Description: 排序(暴力)
11          * 最小到最大排序,然后取前k个
12          * 时间复杂度O(nlogn)
13          * 空间复杂度(logn)
14          */
15         if(arr.length == k) {
16             return arr;
17         }
18         Arrays.sort(arr);
19         int[] temp = new int[k];
20         for(int i = 0; i < k; i++) {
21             temp[i] = arr[i];
22         }
23         return temp;
24     }
 1  public int[] smallestKB(int[] arr, int k) {
 2         /**
 3          * @Method: smallestKB
 4          * @Author: haifwu
 5          * @Version:  1.0
 6          * @Date: 28/05/2021 12:07
 7          * @param arr
 8          * @param k
 9          * @Return: int[]
10          * @Description: 堆
11          * 因为大根堆实时维护数组的前k小值。
12          * 首先将前k个数插入大根堆,
13          * 然后从K+1个数开始遍历,
14          * 比较堆顶元素与第k+1个数,
15          * 若小,不变
16          * 若大,先出堆顶元素放入。
17          * 时间复杂度:O(nlongk)
18          * 空间复杂度:O(k)
19          */
20         int[] temp = new int[k];
21         if(k == 0) {
22             return temp;
23         }
24         if(arr.length == k) {
25             return arr;
26         }
27         PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
28             @Override
29             public int compare(Integer integer, Integer t1) {
30                 return t1 - integer;
31             }
32         });
33         for(int i = 0; i < k; i++) {
34             queue.offer(arr[i]);
35         }
36         for(int i = k; i < arr.length; i++) {
37             if(queue.peek() > arr[i]) {
38                 queue.poll();
39                 queue.offer(arr[i]);
40             }
41         }
42         for(int i = 0; i < k; i++) {
43             temp[i] = queue.poll();
44         }
45         return temp;
46     }
原文地址:https://www.cnblogs.com/haifwu/p/14822166.html