码迷,mamicode.com
首页 > 其他好文 > 详细

寻找最大的K个数

时间:2015-04-20 09:34:08      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:算法   快速排序   二分查找   

技术分享解法一:

技术分享

 

技术分享解法二:

利用快速排序的思想,假设N个数存储在数组S中,我们从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb,Sa中的元素大于等于X,Sb中的元素小于X。
技术分享
伪代码如下:
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])
 //将p加入较小的组,可以避免分组失败,是分组更均匀,提高效率
  length Sa<length Sb? Sa.Append(p):Sb.Append(p)


  return (Sa,Sb)

技术分享解法三:
      采用二分查找的方法,寻找N个数中最大的K个数,本质上就是寻找最大的K个数中最小的那个,也就是第K大的数。假如N个数中最大的数为Vmax,最小的数为Vmin;那么这N个数中的第K大数一定在区间[Vmin,Vmax]之间。那么,可以在这个区间内二分搜索N个数中的第K大数p.
伪代码如下:
   while (Vmax-Vmin>delta)
  {
 Vmid=Vmin+(Vmax-Vmin)*0.5;
 if (f(arr,N,Vmid)>=K)
 {

 Vmin=Vmid;
 }
 else
 Vmax=Vmid;
  }
伪代码中f(arr,N,Vmid)返回数组arr[0,....,N-1]中大于等于Vmid的数的个数.delta的取值要比所有N个数中的任意两个不相等的元素差值之最小值小。


技术分享解法四:
              适用于数据个数N很大的情况,100亿?
技术分享技术分享
技术分享
图2-1是一个堆,用一个数组h[]表示。每个元素h[i],它的父亲节点是h[i/2],儿子是h[2*i+1]和h[2*i+2].没新考虑一个数X,需要进行的更新操作伪代码如下:
 if (X>h[0])
  {
 h[0]=X;
 p=0;
 while (p<K)
 {
 q=2*p+1;
 if (q>=K)
    break;
 if((q<K-1)&&h[q+1]<h[q])
 q=q+1;
 if (h[q]<h[p])
 {
  t=h[p];
  h[p]=h[q];
  h[q]=t;
 }
 else
 break;
 }
  }
时间复杂度为O(N*log2K).
技术分享解法五:
      确定的线性算法。可以通过改进计数排序,基数排序等来得到一个更高效的算法。但是算法的适用范围受到一定的限制。
技术分享
 for(sumCount=0,v=MAX-1;v>=0;v--)
  {
 sumCount+=count[v];
 if (sumCount>=k)
     break;
  }
 return v;
  
技术分享


寻找最大的K个数

标签:算法   快速排序   二分查找   

原文地址:http://blog.csdn.net/wangfengfan1/article/details/45132351

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!