問題:從N個數中找出最大的K個數。linux
首先,要解決的第一件事情,就是這N個數可否所有存入內存。數組
在linux系統中,棧的最大可分配空間是8M,能夠用ulimit -s 命令查看。堆可分配的最大內存空間32位系統和64位系統不一樣。優化
32位系統中,一個進程可尋址的空間只有4G,即2的32次方,據網上說,可分配給堆得空間約2.8G。因此,堆可分配的最大內存 = min(2.8G,剩餘內存大小).net
64位系統中,一個進程可尋址的空間原則上是2的64次方,如今的64位機器通常只使用後48位尋址,那也是258T,如今的內存遠達不到這個量級。因此,堆可分配的最大內存 = 剩餘內存大小。blog
固然,如今都有swap物理空間,因此可分配的堆空間應該比剩餘內存大小要大一些。具體大多少,不是很清楚,須要瞭解swap空間的使用策略。排序
若是,這N個數能夠都存入內存。進程
一、最簡單,也是最低效的方法是:將這N個數排序,取前K個數便可。通常使用快排或者堆排序,快排在實際運用中能更好一些。 o(N*log2N)內存
二、部分快排:不斷劃分區間,直到大的部分的數目爲K。o(N*log2K)it
三、部分堆排序:堆排序的方法是先建堆,而後不斷取堆頂元素,而後從新調整堆。部分堆排序的方法是先將前K個元素建最小堆,而後後面的元素不斷與前K個元素比較,從新調整堆,保證堆頂元素比其他N-K個數都大。o(N*log2K)遍歷
四、尋找第K大的數。先找出第K大數,而後遍歷輸出比第K大的數。利用二分法找第K大的數。o(N*log2N)
五、數組下標法。要求比較多,數要爲整數,並且不能太大。就能夠每一個數做爲數組下標,存放的是該數出現的次數。o(N)
實現:http://blog.csdn.net/xiaoding133/article/details/8037086
總的來講,部分快排和部分堆排序比較靠譜。第一種方法太蠢,方法四雖然能夠優化,但聽說實際效果仍是很差,方法五要求太多,但若是符合要求的話,方法五仍是很高效的。