题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
方法1:红黑树 插入、删除、查找O(logK) 整体时间O(nlogK)
遍历输入,用multiset存储最小的k个数,一旦其中存入K个数后就对头部进行比较 完成插删
不更改输入的内容,适合海量数据
typedef multiset<int,greater<int>> intMs; //从根节点开始删除 最大值在最初位置
typedef multiset<int,greater<int>>::iterator intMsiter;
class Solution {
public:
vector<int> GetLeastN(const vector<int> &input,intMs &res,int k){
int len = input.size();
vector<int> result;
if(len<k||k<=0)
return result;
res.clear();
for(int i=0;i<len;i++){
if(res.size()<k)
res.insert(input[i]);
else{
intMsiter iter = res.begin();
if(*iter>input[i])
{
res.erase(iter);
res.insert(input[i]);
}
}
}
for(intMsiter j=res.begin();j!=res.end();j++){
result.push_back(*j);
}
return result;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if(input.empty())
return input;
intMs temp;
return GetLeastN(input,temp,k);
}
};
方法2:使用快排 O(n) 当快排返回k-1时完成前k个的排序
class Solution {
public:
int Partition(vector<int> &input,int start,int end){ //引用
int index = rand()%(end - start + 1);
swap(input[index],input[end]);
int small = start;
for(index = start;index<end;index++){
if(input[index]<input[end])
{
if(index != small)
swap(input[index],input[small]);
small++;
}
}
swap(input[small],input[end]);
return small;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> result;
if(input.empty()||input.size()<k||k<1)
return result;
int len =input.size();
int start = 0;
int end = len - 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);
}
}
for(int i=0;i<k;i++){
result.push_back(input[i]);
}
return result;
}
};