编程之美——寻找数组中最大的K个数

从别人的那里转过来,这种题目,其实就是需要使用分治方法

编程之美上的寻找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;

}

    原文作者:zhouzhenhe2008
    原文地址: https://blog.csdn.net/zhouzhenhe2008/article/details/77278374
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞