编程之美:第二章 数字之魅 2.5寻找最大的k个数

/*
寻找最大的k个数:
解法1:
如何避免对后N-k个数的排序,选择排序和交换排序都是不错的选择,O(N*k),如果K<=log2N时,那么可以选择部分排序。

解法三:
寻找N个数中最大的K个数,本质就是寻找最大的K个数中最小的那个,也就是第K大的数。可以使用二分搜索,对于一个给定的数p,可以在O(N)的时间复杂度内找到所有
不小于p的数。加入N个数中最大的数为Vmax,最小的数位Vmin,那么这N个数中的第K大数一定在区间[Vmax,Vmin]之间。可以在这个区间内二分搜索N个数中的第K个大数p

解法四:
用set来做,实现留一个k个元素大小的set,
如果数据不能全部装入内存,尽可能少地遍历所有数据。不妨设N > k,前k个数中的最大K个数是一个退化的情况。所有K个数就是最大的K个数。
可以用容量为K的最小堆来存储最大的K个数,最小堆的堆顶元素师最大K个数中最小的一个。若破坏了最小堆的结构,阿么需要O(log2K)来维持堆的性质。

解法5:
用哈希数组来做,假设所有整数在(0,MAXN)区间中,利用一个数组count[MAXN]来记录每个整数出现的次数,只需要扫面一遍就可以得到count数组,然后寻找第k大
元素。
扩展:如果最大的数为Vmax,最小的数为Vmin,那么可以把区间[Vmin,Vmax]分成M块,每个小区间的跨度为d = (Vmax - Vmin)/M,即[Vmin,Vmin+d],
[Vmin+d,Vmin+2d],...,然后扫描一遍所有元素,统计各个小区间中的元素个数,可以知道第k大的元素在哪一个区间,再对那个小区间进行分块处理,
不能保证线性,尽量找一个大的M,但M取值受内存限制。
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值