寻找最大的K个数

解法一:先排序,再取出前K个,总时间复杂度O(n*logN)+O(K)= O(n*logN)。

解法二:快排思想。假设N个数存储在数组S中,我们从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时,有两种可能性:(1)Sa中元素的个数小于K,Sa中所有的数和Sb中最大的K-|Sa|个元素就是数组S中最大的K个数。(2)Sa中元素的个数大于或等于K,则需要返回Sa中最大的K个元素。这样递归下去,不断把问题分解成更小的问题,平均时间复杂度O(N*logK)。(程序实现:选定一个数,然后遍历N-1个数,大于等于K的放入Sa容器,其他放入Sb容器。以此类推。通过程序可以推出时间复杂度,函数体是N,递归一般K中分,递归集中在后面Kbig(Sb,k-lengthSa))

解法三:寻找N个数中最大的K个数,本质上就是寻找最大的K个数中最小的那个,也就是第K大的数。可以使用二分搜索的策略来寻找N个数中的第K大的数。时间复杂度为O(N*logN)。在整数的情况下还可以从另一角度来看这个算法:假设所有整数的大小都在[0,2^(m-1)]之间,我们可以先考察二进制位的第(m-1)位,将N个整数按该位为1或者0分为两个部分,也就是将整数分为取值为[0,2^(m-1)-1]和[2^(m-1),2^m-1]两个区间。如果该位为1的整数个数A大于等于K,那么,在所有该位为1的整数中继续寻找最大的K个。否则,在该位为0的整数中寻找最大的K-A个。接着考虑二进制位第(m-2)位,以此类推。

解法四(用以对付大数据):用最小堆存储该最大K个数。从大数据中取一个数,如果比最小堆树根小,则添入树根,调整最小堆,以此类推。该方法只需要扫描所有的数据一次,时间复杂度为O(N*logK)。(logK为调整堆所用的时间)。

解法五:如果所有N个数都是正整数,且它们的取值范围不太大,可以考虑申请空间,记录区间中每个整数出现的次数,再从大到小取最大的K个。极端情况下,如果N个整数各不相同,我们甚至只需要一个bit来存储这个证书是否存在就可以了。不是整数也可以用这个思想,存储的是一个区间的数字数目就可以了。比如Vmax-Vmin为N个数最大与最小的差,则d=(Vmax-Vmin)/M,分成M份,可以取[Vmin,Vmin+d],[Vmin+d,Vmin+2d]在递归对区间做处理即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值