题目描述:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

思路1:最直接的思路是对数组中的元素从小到大进行排序,然后将前K个元素存放在res中即可。需要注意一个边界条件:当k大于给定数组中元素个数时,返回空

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if(k>input.size())//无效输入
return {};
sort(input.begin(),input.end());
vector<int> res;
for(int i=0;i<k;i++)
res.push_back(input[i]);
return res;
}
};

思路2:使用快速排序的思想 时间复杂度O(n)

class Solution {
public:
//思路:采用快速排序的思想,找到第k大的数字num,num左边的都是比其小的数字(result),num右边的数字都是比其大的数字
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
//需要做好判断条件,把细节处理好
if(k<=0||input.empty()||k>input.size())
return {};
if(k==input.size())
return input;
int start=0;
int end=input.size()-1;
int index=Partition(input,start,end);
while(index!=k-1){
if(index>k-1){
end=index-1;
index=Partition(input,start,end);
}else{
start=index+1;
index=Partition(input,start,end);
}
}
vector<int>::iterator first=input.begin();
vector<int>::iterator last=input.begin()+k;
vector<int> res(first,last);
return res;
}
int Partition(vector<int>& input,int start,int end){
int low=start;
int high=end;
int pivot=input[low];
while(low<high){
while(low<high&&input[high]>=pivot)
high--;
input[low]=input[high];
while(low<high&&input[low]<pivot)
low++;
input[high]=input[low];
}
input[low]=pivot;
return low;
}
};

思路3:使用STL容器multiset,multiset是基于红黑树实现的,插入、删除的时间复杂度都是O(logn)
创建一个multiset,用于存放最小的k个数。遍历input,如果multiset中元素个数还没有超过k,则直接添加到multiset中,如果达到k个数了,则需要将multiset中最大的元素和要插入的元素进行比较,如果要插入的元素比multiset中最大的元素大,则抛弃,反之,则进行替换。

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if(k<1||input.empty()||k>input.size())
return {};
for(it=input.begin();it!=input.end();it++){
if(s.size()<k){
s.insert(*it);
}else{
max=s.begin();
if(*it<*max){
s.erase(max);
s.insert(*it);
}
}
}
for(max=s.begin();max!=s.end();max++)
res.push_back(*max);
return res;
}
private:
//greater<int>是从大到小排序的函数 #include <functional>
multiset<int,greater<int>> s;
vector<int>::iterator it;
multiset<int,greater<int>>::iterator max;
vector<int> res;
};