题目分析:[[EVD]] - 剑指 Offer 40. 最小的k个数
https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/
简单描述:
- 整数数组中找出其中最小的 k 个数
限制🚫
- 0 <= k <= arr.length <= 10000
- 0 <= arr[i] <= 10000
示例:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
解题思路:
思路:
- #排序
- #快速排序
- 快排后输出前k个
- 快排过程判断基准值下标是否为k.是则结束(⚠️题目只要求给出最小k个数并无要求按顺序依次给出)
- #堆 先放入k个数,然后放剩余的数,放之前和堆顶比较,将小的放入堆中
- 利用 #[[C++ STL]]中的优先队列priority_queue(底层实现为堆,默认大根堆,可指定为小根堆)
- 补充: #[[C++ STL]]中不同容器之间是不能直接赋值的,assign函数可以实现不同容器但相容的类型赋值
效率:
- 时间复杂度
- 空间复杂度
代码:
- 1.快速排序 没有自己实现,可套快排模板,借用库函数sort(底层实则为混合排序)
class Solution {
public:
/*快排后输出前k个*/
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> res;
sort(arr.begin(),arr.end());
for(auto n:arr){
res.push_back(n);
if(--k == 0)
break;
}
return res;
}
};
- 2.堆排序 没有自己实现,可套堆排序模板,借用priority_queue
class Solution {
public:
/*大根堆*/
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> vec;
if (k == 0) {
return vec;
}
priority_queue<int> Q;
for (int i = 0; i < k; ++i) {
Q.push(arr[i]);
}
for (int i = k; i < arr.size(); ++i) {
if (Q.top() > arr[i]) {
Q.pop();
Q.push(arr[i]);
}
}
while(k--){
vec.emplace_back(Q.top());
Q.pop();
}
return vec;
}
};