题 目:若是在N个数中找出其中前K大的数?数组
思路一:分布式
先对N个数进行排序,而后在取其前K大的数;(冒泡排序,快速排序等)spa
思路二:排序
部分排序,只排除前K大的数便可(使用选择排序进行部分排序,选择排序的时间复杂度O(N2))事件
思路三:内存
我能够用分治法,这有点相似快排中partition的操做。随机选一个数t,而后对整个数组进行partition,会获得两部分,前一部分的数都大于t,后一部分的数都小于t。资源
若是说前一部分总数大于1000个,那就继续在前一部分进行partition寻找。若是前一部分的数小于1000个,那就在后一部分再进行partition,寻找剩下的数。it
该思路的事件复杂度为O(N):首先,partition的过程,时间是o(n)。咱们在进行第一次partition的时候须要花费n,第二次partition的时候,数据量减半了,因此只要花费n/2,同理第三次的时候只要花费n/4,以此类推。而n+n/2+n/4+...显然是小于2n的,因此这个方法的渐进时间只有o(n)。io
思路四:方法
当N的值过大,且内存资源有限,没法一次读取所有数据时,能够考虑分布式的实现,将数据切分,而后在多台机器上分别计算前K大的数,最后在把这些数据汇总。
思路五:
使用最小堆思想。即在内存中维护一个有K个数组成的最小堆;根据最小堆每个节点都要比他的左右直接点小的性质:
首先从N个数中取K个数构成最小堆;
而后依次读取剩余数据,而且和堆顶元素比较大小,若是比堆顶小,则直接丢弃。若是比堆顶大,就替换堆顶,并调整最小堆;
全部数据都处理完毕后,最小堆就是N个数中前K大的数。
优势是:数据只须要读取一次,不会存在数据屡次读写的问题;
【思路五的C++实现】
【待更新。。。。】