在大规模的数据处理中,,遇到寻找出最大的前K个数,或最小的前K个数。快速排序法是时间复杂度为O(n)的方法,或者使用堆,时间复杂度为O(nlogk),空间复杂度为O(1)
解法一:O(n),缺点修改了输入数组
void GetLeastNumbers(int* input ,int n,int *output,int k)
{
if(input==NULL||output==NULL||k>n||n<=0||k<=0)
return;
int start=0;
int end=n-1;
int index=Partition(input,n,start,end);
while(index!=k-1)
{
if(index>k-1)
{
end=index-1;
index=Partition(input,n,start,end);
}
else
{
start=index+1;
index=Partition(input,n,start,end);
}
}
for(int i=0;i<k;++i)
output[i]=input[i];
}
int Partition(vector<int>& input, int begin, int end)
{
int low=begin;
int high=end;
int pivot=input[low];
while(low<high)
{
while(low<high&&pivot<=input[high])
high--;
input[low]=input[high];
while(low<high&&pivot>=input[low])
low++;
input[high]=input[low];
}
input[low]=pivot;
return low;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int len=input.size();
if(len==0||k>len) return vector<int>();
if(len==k) return input;
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);
}
}
vector<int> res(input.begin(), input.begin() + k);
return res;
}
解法二:O(nlogk)的的算法,特别适合处理海量数据
大小为K的容器,找出最大值,与剩下的数据比较
最大堆 O(1)找出已知K个数的最大值,O(logk)时间删除及插入
红黑树实现我们的容器,STL中set和multiset基于红黑树
typedef multiset<int ,greater<int>> intset;
typedef multiset<int ,greater<int>>::iterator setIterator;
void GetLeastNumbers(const vector<int>&data,inset& leastNumbers,int k)
{
leastNumbers.clear();
if(k<1||data.size()<k)
return;
vector<int>::const_iterator iter=data.begin();
for(;iter!=data.end();++iter)
{
if((leastNumbers.size())<k)
leastNumbers.insert(*iter);
else
{
setIterator iterGreatest=leastNumbers.begin();
if(*ter<*(leastNumbers.begin()))
{
leastNumbers.erase(iterGreatest);
leastNumbers.insert(*iter);
}
}
}
}
//最适合情形n很大,k较小 海量数据处理,从海量数据中找出最小的k个数字
3)全排序
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.empty()||k>input.size()) return res;
sort(input.begin(),input.end());
for(int i=0;i<k;i++)
res.push_back(input[i]);
return res;
}