面试题 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 }
标签:面试题,return,temp,int,复杂度,个数,arr,17.14,排序 来源: https://www.cnblogs.com/haifwu/p/14822166.html