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

23 篇文章 1 订阅
16 篇文章 0 订阅

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


编程之美上的寻找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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值