N个元素取出最大(小)的K个元素

来源:互联网 发布:店铺怎么用淘宝客 编辑:程序博客网 时间:2024/05/20 04:12

题目要求:N个元素取出最大(小)的K个元素,请说明思路及算法。

注:每个方法都有其适用范围,比如有的在N数目很大的情况下适用。

方法一:首先对元素进行排序,然后去除最大的K个元素即可。可以用基本的直接插入排序、冒泡排序,也可以用快速排序和堆排序等方法来解决。一般来说都会要求快速排序,因为该方法综合来说是最好的。

快速排序版本1:该方法是算法导论上提出的,比较的思想是:从最开始的元素来与我们选定的元素(最右边元素)来比较,如果大于选定的元素,则不处理,如果小于选定的元素,就会往前替换。

[cpp] view plaincopyprint?
  1. int Partition(int A[],int p,int r) //非递减排序方法  
  2. {  
  3.     int x = A[r];  
  4.     int i = p-1,mid;  
  5.     for(int j=p;j<r;j++)  
  6.     {  
  7.         if(A[j] <= x)             //寻找小于x的数据,找到以后会往前交换  
  8.         {  
  9.             i=i+1;  
  10.             if(i!=j)               //不相等的才需要交换,算法导论上直接交换了,这里感觉可以优化  
  11.             {  
  12.                 swap(&A[i],&A[j]);  
  13.             }  
  14.         }  
  15.     }  
  16.     swap(&A[i+1],&A[r]);  
  17.     return i+1;  
  18. }  
  19. void QuickSort(int A[],int p,int r)  
  20. {  
  21.     int q;  
  22.     if(p<r)  
  23.     {  
  24.         q = Partition(A,p,r);  //得到q以后递归调用  
  25.         QuickSort(A,p,q-1);  
  26.         QuickSort(A,q+1,r);  
  27.     }  
  28. }  
 

快速排序版本2:一般的方法,从两边开始比较。

[cpp] view plaincopyprint?
  1. int Partition1(int a[],int low,int high)  
  2. {    
  3.   int pivotkey;  
  4.   pivotkey = a[low];                         //枢纽记录关键字  
  5.   while(low < high)                                    //从表的两端交替地想中间扫描  
  6.   {  
  7.     while(low < high&& a[high] >=pivotkey)  
  8.         --high;  
  9.     a[low] = a[high];                   //将比枢纽小的移到低位  
  10.     while(low<high&& a[low] <=pivotkey)  
  11.         ++low;  
  12.     a[high] = a[low];                   //将比枢纽大的移到高位  
  13.   }                                               
  14.   a[high] = pivotkey;                          //枢纽记录到位  
  15.   return high;                                 //返回枢纽位置  
  16. }  
  17. void QuickSort(int A[],int p,int r)  
  18. {  
  19.     int q;  
  20.     if(p<r)  
  21.     {  
  22.         q = Partition1(A,p,r);  //得到q以后递归调用  
  23.         QuickSort(A,p,q-1);  
  24.         QuickSort(A,q+1,r);  
  25.     }  
  26. }  
 

方法2:用一个最小堆来保存K个数,然后从第K+1个开始依次遍历数组,如果大于堆顶元素,则替换堆顶元素,重新调整堆。最后保留下的就是最大的K个元素。

方法3:利用hash保存数组中元素Si出现的次数,利用计数排序的思想,线性从大到小扫描过程中,前面k个数则为所求,平均情况下时间复杂度O(n)

方法4:编程之美上的思路

首先找到最大的第K个数。这个时间复杂度可以做到O(N),具体做法如下:

从N个数中随机选择一个数,扫描一遍,比n大的放在右边,r个元素,比n小的放左边,l个元素
如果:  a:l = K-1   返回n
            b:l > K-1 在l个元素中继续执行前面的操作。
            c:l < K-1  在r个元素中继续执行前面的操作。
b,c每次只需执行一项,因此平均复杂度大概为:O(n+n/2+n/4...)=O(2n)=O(n)
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 途观l前减震异响怎么办 锦明8代声音太大怎么办 手机网页无法加载插件怎么办 微信公众号被投诉怎么办 住了酒店的尾房怎么办 喜欢前任的闺蜜怎么办 闺蜜给介绍对象怎么办 喜欢对象的发小怎么办 山东省直医保卡丢失怎么办 高铁票如果错过了怎么办 动车错过了时间怎么办 长途动车错过了怎么办 动车如果错过了怎么办 没有取票错过了怎么办 动车出站没检票怎么办 火车晚点耽误了下班车怎么办 动车票中途丢了怎么办 购买二手房异地铁路公积金怎么办 沈阳公积金卡丢了怎么办 住宅专项维修资金用完了怎么办 广州出租车丢了东西怎么办 广州的士丢了东西怎么办 网上找兼职被骗了怎么办 海信空调开不了机怎么办 海信空调遥控器开不了怎么办 学生遭套路贷反被仲裁怎么办 赏脸打错字尝脸怎么办 红掌的花变黑了怎么办 红掌花苞发黑了怎么办 水培植物腐根了怎么办 水培绿萝水发臭怎么办 水里养花根烂掉怎么办 桅子花叶子发黑怎么办 大株月季烂根怎么办 月季水浇多了烂根的怎么办 金桔盆栽烂根怎么办 盆栽的长寿果树烂根怎么办 家里的石榴烂根怎么办 山桔盆栽烂根怎么办 养的植物烂根怎么办 桅子花叶子长霉怎么办