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

有很多个无序数,我们姑且假定他们各不相等,怎么挑选出其中最大的若干个数呢?

        如果这个数据量很大,比如1亿个,如果所存数据是浮点型呢?我们该怎么处理呢?

分两部分,第一部分是我个人的解答,第二部分是书上的解答;

第一部分:


    1,如果这个问题里的数据都是整数,这个问题利用hash映射应该很简单,就是在开辟一个数组,把原数组里的数据map到新开辟的数组里,如:原数组里有数据123,则在新开辟数组的123位置上填入1,。然后对新开辟的数组从后往前扫描,记录值为1的数组的下标。整个过程的时间复杂度O(n+k),n是原数组的大小,k是数组里最大数据的大小;空复杂度为O(k)。这种解法对空间的要求大,时间上是线性的,可以接受。

  

   ,2, 考虑到不能开辟新的空间的话,可以利用快速排序,时间复杂度n(lgn),然后取出前k个,总的复杂度为O(nlgn+k);利用优先队列,复杂度:O(nlgn);


   ,3,如果数据是浮点数,我们可以采用类似桶排序的思想,新开辟一个空间

           

                                                                 图 A

书上的答案:

          1,对于小数据量,快速排序或是堆排序,f复杂度O(NlgN)+O(K);选择排序,复杂度O(N*K);

           2,利用快速排序的思想,把大问题化成小问题,引用原书上上的话:

              

         总结:我们对于排序类的问题,无非三种思路,要么利用现有排序(或是对其进行改进),要么用空间换时间,要么大问题化小问题,这里结合了第一种情况和第二种情况;

          3,如果数据量很大呢,比如100亿,推荐使用小顶堆;时间复杂度O(NlgN);

          4, 利用线性排序的思想,空间换时间;


          扩展:

          懒得打字,我全拍下来,然后一个个分析吧。



题1:很明显,直接上桶排序,如图A;

题2:用空间换时间最快了,直接扫苗;也可以利用堆排序,直接获取k到m之间的数,还可以选择排序;复杂度都是O((m-k)lgN);

题3:维护一个堆最好了(小顶堆);

题4和题5  看不懂。


此题还可以扩展成为:求一个数组里第k大的数。

思路:

       1  排序吧,快排/堆排,复杂度O(NlgN)+O(K);

       2,空间换时间,复杂度O(N)+O(LEN);

       3,选择排序,时间复杂度O(kN);

       4 ,以上算法在控制空间的情况下,复杂度始终没有突破O(N),如果采用分治,类似快排的思想,第一趟数据分割后,比较中间数据左右的个数与k的大小,复杂度为O(N);

      第二趟继续,复杂度为O(N/2),一直到复杂度为O(N/2^K)。总的复杂度O(2N);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值