从别人的那里转过来,这种题目,其实就是需要使用分治方法
编程之美上的寻找N个数中最大的前K数,给出了一种算法,我认为比较好:
算法是这样写的:
假设N个数存储在数组S中,我们从数组S中随机选出一个元素X,把数组分为两部分Sa和Sb.Sa中的元素都大于X,Sb中的元素都小于X,这时,有两种可能性:
1.Sa中元素的个数小于K,Sa中所有的数和Sb中最大的K-|Sa|个数(|Sa|指Sa中元素的个数)就是数组S中最大的K个数。
2.Sa中元素的个数大于或等于K,则直接返回Sa中最大的K个元素。
平均时间复杂度O(N*log2 K)
伪代码如下:
Kbig(S,K)
if(k<=0):
return []
if(length S<=K):
return S
(Sa,Sb)=Partition(s)
return Kbig(Sa,k).Append(Kbig(Sb,k-length Sa)
//////////////////////////////////////////////////
Partition(S):
Sa=[];
Sb=[];
Swap(s[1],S[random()%length S])
p=S[1]
for i in [2:length S]:
s[i] > p ? Sa.Append(s[i]):Sb.Append(S[i])
length Sa
return (Sa,Sb)
本人实现的代码:
// MicroSTest2.cpp : Defines the entry point for the console application.
//
#include “stdafx.h”
#include
#include
#include
#include
using namespace std;
vector Append(vector & A , vector & B)
{
if(B.size()<=0)
return A;
for(int i=0;i
A.push_back(B[i]);
return A;
}
pair , vector> PartitionFun(vector origin)
{
srand((unsigned)time(NULL));
vector Sa , Sb;
pair , vector> res;
int tmp1 = origin[0];
int tmp2 = origin[rand()%origin.size()];
origin[0] = tmp2;
origin[rand()%origin.size()] = tmp1;
int p = origin[0];
for(int i=1;i
origin[i]>p ? Sa.push_back(origin[i]) : Sb.push_back(origin[i]);
Sa.size()
res = make_pair(Sa,Sb);
return res;
}
vector Kbig(vector & S , int k)
{
pair,vector > ret;
vector sa,sb,tmp;
if( k <= 0 )
return S;
if( k >= S.size() )
return S;
ret = PartitionFun(S);
sa = ret.first;
sb = ret.second;
if(sa.size()>=k)
return Kbig(sa,k);
else{
tmp = Kbig( sb , k-sa.size() );
return Append(sa,tmp);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int A[] = {9,3,6,2,3,8,5,3,6,9,7,4,2,4,6,4,9,6,3,2};
vector myvect(A,A+sizeof(A)/sizeof(int));
// vector tmpvect(A+3,A+15);
// myvect = Append(myvect,tmpvect);
cout<<“数组长度是 “<<myvect.size()<<endl;
cout<<“数组最大长度是 “<<myvect.max_size()<<endl;
cout<<“数组容量是 “<<myvect.capacity()<<endl;
myvect.push_back(88);
myvect.push_back(8);
cout<<“数组长度是 “<<myvect.size()<<endl;
cout<<“数组最大长度是 “<<myvect.max_size()<<endl;
cout<<“数组容量是 “<<myvect.capacity()<<endl;
//排序前
for(int i=0;i
cout<<myvect[i]<<” “;
cout<<endl;
//对数组排序
// sort(myvect.begin() , myvect.end()); /// /小到大
// reverse(myvect.begin(),myvect.end()); /// 从大道小
//排序后,对元素的修改
for(int i=0;i
cout<<myvect[i]<<” “;
cout<<endl<<“—————————-“<<endl;
vector res = Kbig(myvect,6);
for(int i=0;i
cout<<res[i]<<” “;
cout<<endl;
system(“pause”);
return 0;
}