问题描述
输入整数数组
,找出其中最小的
个数。
:
arr = [3,2,1], k = 2
:[1,2] 或者 [2,1]
解题报告
- 方法一:堆
维护大小为k的堆,当遍历完数组时,输出堆中的元素。
: ,维护大小为k的堆,复杂度为 ,最坏情况下数组里的 个数都会插入,所以时间复杂度一共是
: - 方法二:快速排序
借助基准线,一次划分之后,只需要处理其中一边的元素。
:最好的情况: ,最坏的情况: ,每次的划分点都是最大值或最小值,一共需要划分 次,而一次划分需要线性的时间复杂度。
:
实现代码
- 堆
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
priority_queue<int>pq;
vector<int>ans(k);
if(k==0) return ans;
for(int i=0;i<k;i++){
pq.push(arr[i]);
}
for(int i=k;i<arr.size();i++){
if(pq.top()>arr[i]){
pq.pop();
pq.push(arr[i]);
}
}
for(int i=0;i<k;i++){
ans[i]=pq.top();
pq.pop();
}
return ans;
}
};
- 快速排序
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
int n=arr.size();
if(n==k) return arr;
if(n<k || k<=0 || n==0) return vector<int>();
int l=0,r=n-1;
int index=partition(arr,l,r);
while(index!=k-1){
if(index>k-1) r=index-1;
else l=index+1;
index=partition(arr,l,r);
}
return vector<int>(arr.begin(),arr.begin()+k);
}
int partition(vector<int>&arr,int l,int r){
int temp=arr[l];
while(l<r){
while(l<r && arr[r]>=temp) r--;
arr[l]=arr[r];
while(l<r && arr[l]<=temp) l++;
arr[r]=arr[l];
}
arr[l]=temp;
return l;
}
};