剑指offer. 40 最小的k个数 top(k)(重要)
题目描述:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
解题思路:
解法1: 快速选择,定位下标为k-1的数,O(n)
解法2: 海量数据top k问题。 大(小)顶堆(O(nlogk))
假如求最小的k个,用大顶堆 priority_queue<int> big_heap;
假如求最大的k个,用小顶堆 priority_queue<int,vector<int>,greater<int> > small_heap。
比如这一题最小的k个,那用大顶堆,来了一个新的假如比堆顶heap.top(),也就是堆里面最大的还要小,那堆顶滚出去,这个加进来。否则略过 ,下一个。
解法1代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int len=input.size();
if(k<=0 || len==0 || len<k)
return {};
int left=0,right=len-1;
int index=partition(input,left,right);
while(index !=k-1){
if(k-1<index){
right=index-1;
} else{
laeft=index+1;
}
index=partition(input,left,right);
}
vector<int> res(k);
for(int i=0;i<k;++i){
res[i]=input[i];
}
return res;
}
int partition(vector<int> & vec, int left,int right){
int pivot=vec[left];
int less=left;
for(int i=left+1;i<=right;++i){
if(vec[i]<pivot)
swap(vec[i],vec[++less]);
}
swap(vec[left],vec[less]);
return less;
}
};
解法2代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int len =input.size();
if(k<=0 || len==0 || len< k )
return {};
vector<int> res;
priority_queue<int> helper;
for(int i=0;i!=k;++i){
helper.push(input[i]);
}
for(int i=k;i!=len;++i){
if(input[i]<helper.top()){
helper.pop();
helper.push(input[i]);
}
}
for(int i=0;i!=k;++i){
res.push_back(helper.top());
helper.pop();
}
return res;
}
};