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

问题:寻找最大的K个数。

解法1:对于N个数,先取前K个数建立一个小根堆,此时根顶元素是最小的,另外剩余N-K个元素,取出一个与小根堆堆顶元素比较,如果大于堆顶元素,则替代之,再进行堆的调整,对于其余的N-K-1个元素也是这样,分别于堆顶元素比较,当比较完的时候,这时的K个元素的堆就变成了最大的K个数。另外这种方法同时得到了前K大个数中最小的那个即堆顶元素。即得到了第K大元素。

   用容量为K的最小堆来存储最大的K个数。最小堆的堆顶元素就是最大K个数中的最小的一个。每次扫描一个数据X,如果X比堆顶元素Y小,则不需要改变原来的堆。如果X比堆顶元素大,那么用X替换堆顶元素Y,在替换之后,X可能破坏了最小堆的结构,需要调整堆来维持堆的性质。调整过程时间复杂度为O(logK)。 全部的时间复杂度为O(N*logK)。这种方法当数据量比较大的时候,比较方便。因为对所有的数据只会遍历一次。


解法2利用快速排序,随便找一个分割点key,这样进行一趟排序后,就把数分成了3部分,以key为边界,左边都是比它小的(大的也行),右边都是比它大的。假定左边大,右边小,如果K正好等于左边的个数,那么左边即前K大数,如果K大于左边的个数,再从右边的找。。。。。

   假设N个数存储在数组S中,从数组中随机找一个元素X,将数组分成两部分Sa和Sb.Sa中的元素大于等于X,Sb中的元素小于X。
    出现如下两种情况:
   (1)若Sa组的个数大于或等于K,则继续在sa分组中找取最大的K个数字 。
   (2)若Sa组中的数字小于K ,其个数为T,则继续在sb中找取 K-T个数字 。
   一直这样递归下去,不断把问题分解成小问题,平均时间复杂度为O(N*logK)。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值