面试题40:最小的k个数(C++)
题目地址:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/
题目描述
输入整数数组 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个数即可。
大根堆:使用一个大根堆(优先队列)实时维护数组的前 k小值。首先将前 k个数插入大根堆中,随后从第 k+1个数开始遍历,如果当前遍历到的数比大根堆的堆顶的数要小,则将堆顶的数弹出,然后插入当前遍历到的数。最后将大根堆里的数存入数组返回即可。
程序源码
传统法
class Solution { public: vector<int> getLeastNumbers(vector<int>& arr, int k) { vector<int> arr1(k, 0); sort(arr.begin(), arr.end()); for(int i = 0; i < k; i++) arr1[i] = arr[i]; return arr1; } };
大根堆
class Solution { public: vector<int> getLeastNumbers(vector<int>& arr, int k) { if(arr.empty() || k == 0) return {}; vector<int> res; priority_queue<int> que; for(int i = 0; i < k; i++) { que.push(arr[i]); } for(int j = k; j < arr.size(); j++) { if(que.top() > arr[j]) { que.pop(); que.push(arr[j]); } } for(int i = 0; i < k; i++) { res.push_back(que.top()); que.pop(); } return res; } };
-----------------------------------
心之所向,素履所往;生如逆旅,一苇以航。
------------------------------------------