剑指 Offer 40. 最小的k个数(简单)

通过率 56.9%

题目链接

题目描述:

输入整数数组 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

思路:

1. 库函数 sort + slice

2. 堆 C++可以直接用priority_queue优先队列,遍历数组,用优先队列维护最小的k个值,一旦当前遍历到的数小于大顶堆堆顶的数,就将堆顶的数弹出让当前的数入队,最后返回该优先队列中的数

3. 快速排序 每排一次都会将数组分为两组排序,设分割点的值为x,那么左边那组数都比x小,右边的都比x大,于是,当x===k-1时,直接返回数组前k个数(由题可知,返回的数组可以无序,只要保证是前k小的数就行);当x<k-1,则只须排右边那组;当x>k-1,只须排左边那组

代码:

1. 库函数 sort + slice

 1 /*JavaScript*/
 2 /**
 3  * @param {number[]} arr
 4  * @param {number} k
 5  * @return {number[]}
 6  */
 7 var getLeastNumbers = function(arr, k) {
 8     arr.sort((a, b) => a - b)
 9     return arr.slice(0, k)
10 };

2. 堆(优先队列)

 1 /*C++*/
 2 class Solution {
 3 public:
 4     vector<int> getLeastNumbers(vector<int>& arr, int k) {
 5         vector<int> res;
 6         priority_queue<int> q;
 7 
 8         if(!k) return res;
 9         for(int i = 0; i < k; i++) {
10             q.push(arr[i]);
11         }
12         for(int i = k; i < arr.size(); i++) {
13             if(arr[i] < q.top()) {
14                 q.pop();
15                 q.push(arr[i]);
16             }
17         }
18         while(q.size()) {
19             res.push_back(q.top());
20             q.pop();
21         }
22         return res;
23     }
24 };

3. 快排

这里将第一个数作为基准点会好分析一些,最后跳出循环时一定是i===j,而以其他数作为基准点的话我往往很难确定到底是i还是j是分割点,分治就是这点令人头疼,不知道分到最后是个什么情况,说到底还是对这个不熟

 1 /*JavaScript*/
 2 /**
 3  * @param {number[]} arr
 4  * @param {number} k
 5  * @return {number[]}
 6  */
 7 var quickSort = function(arr, left, right) {
 8     let i = left, j = right, v = arr[left]
 9     while(i < j) {
10         while(i < j && arr[j] >= v) j--
11         arr[i] = arr[j]
12         while(i < j && arr[i] <= v) i++
13         arr[j] = arr[i]
14     }
15     arr[i] = v
16     return i
17 }
18 
19 var partition = function(arr, left, right, k) {
20     const x = quickSort(arr, left, right, k)
21     if(x === k) return arr.slice(0, k)
22     return x < k ? partition(arr, x + 1, right, k) : partition(arr, left, x - 1, k)
23 }
24 
25 var getLeastNumbers = function(arr, k) {
26     return partition(arr, 0, arr.length - 1, k)
27 };

 

posted @ 2021-08-31 12:23  自在逍遥处  阅读(25)  评论(0编辑  收藏  举报