以前一次面试的时候碰到这道题,大概是所有数存储在10MB的文件中,要求取出排在前50项的数。

难得的一次面算法回答的比较好的=’=!当时就想到使用一个大小为K的最小堆,这样只需要扫描一遍文件就可以把最大的K项取出来。这样的时间复杂度是O(N*logK)

之后前一阵帮老师做序列模式挖掘的实验我也用这个思想来保存top k个最大模式。

 

今天随手点开编程之美发现同样这个话题。使用最小堆是一种较优的算法,特别是对大文件处理。

而对小的数组,使用类快速排序的方法也很有意思

大概思路:要去top K个,先从数组中随机找一个元素x,将数组分为两部分Sa,Sb,

1. 若大的部分Sa小于k个元素,则全部返回,并且递归从小的部分Sb中去找K-|Sa|个元素。

2.若Sa元素个数大于等于k,则递归从Sa中找top k

时间复杂度同样O(N*logk),同样这个思路可以用来找第K大的数(像老大问的那道题一样,若k较小,时间复杂度是O(N) )

 

此外,对于特殊情况如全是一定范围的整数可以使用计数排序,使用count[max]数组来对整数计数,最后一遍反向扫描count[]收集top k.

这样的方法可以达到O(N)时间