一、10亿个数中取前1000大的数
1.排序法:
先排序,再取前1000
缺点:时间复杂度高
2.分治法:
类似快排中partition的操作,随机选一个数t,然后对整个数组进行partition,会得到两部分,前一部分的数都大于t,后一部分的数都小于t。
如果前一部分数大于1000个,就继续在前一部分进行partition寻找;
如果前一部分的数小于1000个,那就在后一部分再进行partition,寻找剩下的数
partition的过程,时间是o(n)
第一次partition的时候需要花费n,第二次partition的时候,数据量减半了,所以只要花费n/2,同理第三次的时候只要花费n/4,以此类推。而n+n/2+n/4+...显然是小于2n的,所以这个方法的渐进时间只有o(n)
3.分布式
将数据切分,然后在多台机器上分别计算前1000大的数,最后再把这些数汇总
4.堆排序法
维护一个1000个节点的小顶堆
1.取前1000个数,构成小顶堆
2.然后从文件中读取数据,并且和堆顶大小相比,如果比对顶还小,就直接丢弃
3.如果比堆顶大,就替换堆顶,并调整最小堆
小顶堆特点:每一个节点都小于等于它的左右子节点
每次调整小顶堆的时间复杂度为logk 其中,k为小顶堆节点数
时间复杂度O(nlogk)
二、合并k个有序数组(升序)
取k个数组中的第一个元素,创建一个大小为k的小顶堆
重复操作:
取堆顶元素存入数组,元素的数组的下一位替换上来,小顶堆重新排序
时间复杂度O(nlogk)