17常见算法topN问题
Posted long-w
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了17常见算法topN问题相关的知识,希望对你有一定的参考价值。
题 目:如果在N个数中找出其中前K大的数?
思路一:
先对N个数进行排序,然后在取其前K大的数;(冒泡排序,快速排序等)
思路二:
部分排序,只排除前K大的数即可(使用选择排序进行部分排序,选择排序的时间复杂度O(N2))
思路三:
我可以用分治法,这有点类似快排中partition的操作。随机选一个数t,然后对整个数组进行partition,会得到两部分,前一部分的数都大于t,后一部分的数都小于t。
如果说前一部分总数大于1000个,那就继续在前一部分进行partition寻找。如果前一部分的数小于1000个,那就在后一部分再进行partition,寻找剩下的数。
该思路的事件复杂度为O(N):首先,partition的过程,时间是o(n)。我们在进行第一次partition的时候需要花费n,第二次partition的时候,数据量减半了,所以只要花费n/2,同理第三次的时候只要花费n/4,以此类推。而n+n/2+n/4+...显然是小于2n的,所以这个方法的渐进时间只有o(n)。
思路四:
当N的值过大,且内存资源有限,无法一次读取全部数据时,可以考虑分布式的实现,将数据切分,然后在多台机器上分别计算前K大的数,最后在把这些数据汇总。
思路五:
使用最小堆思想。即在内存中维护一个有K个数组成的最小堆;根据最小堆每一个节点都要比他的左右直接点小的性质:
首先从N个数中取K个数构成最小堆;
然后依次读取剩余数据,并且和堆顶元素比较大小,如果比堆顶小,则直接丢弃。如果比堆顶大,就替换堆顶,并调整最小堆;
所有数据都处理完毕后,最小堆就是N个数中前K大的数。
优点是:数据只需要读取一次,不会存在数据多次读写的问题;
【思路五的C++实现】
【待更新。。。。】
以上是关于17常见算法topN问题的主要内容,如果未能解决你的问题,请参考以下文章