/*
寻找最大的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取值受内存限制。
*/