寻找最大的K个数

无序的N个数,求其中最大的K个数(转载自编程之美)

思路1:排序
快排或堆排序后取最大的K个数,时间复杂度O(NlogN)。
但后N-K个数的排序是无必要的,因此可采用选择排序或交换排序进行部分排序,时间复杂度O(N*K)。

思路2:利用快排partition
快速排序的partition是把N个数分成2部分,前半部分均小于pivot,后半部分均大于pivot。
先利用partition将N分为arr[a]<=pivot<=arr[b],此时有2种情况。
A. a小于K,则{arr[a]的所有数} + {arr[b]中的最大的K-|arr[a]|个数}即为解。
B. a大于K,则{arr[a]中的最大的K个数}即为解。
由此递归下去,平均时间复杂度O(NlogK)。

思路3:按位划分
设N个数的范围为[0-2^m-1]。按照第m-1位是否为1,可以将arr[N]分为2个部分。该位为1的数arr[b1]的个数A,该位为0的数arr[b0]的个数为B。
A. A小于K,则解为{arr[b1]的全部} + {arr[b0]的最大K-A个数}
B. A大于K,则解为{arr[b1]的全部}

!!!!若N很大,无法一次装入内存!!!!

思路4:最小堆
用一个最小堆h来维护当前最大的K个数。
arr[0]~arr[K-1],则是建堆的过程。
arr[K]~arr[N-1],根据当前元素arr[i]与堆顶最小元素h[0]大小关系,来替换或维持当前堆顶元素。若堆顶被替换,需要更新堆。
最小堆可用一个数组来维护(完全二叉树)。

思路5:
若arr[N]的范围(0-MAXN)不是很大,则可以通过维护一个简单的数组hash统计各个整数出现的次数。
使用数组count[MAXN],其中count[i]表示数i的出现个数。
然后扫描一遍count数组即可找到最大的K个数。

极端情况下,如果N个数各不相同,则只需用一个bit来统计该数是否出现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值