竹石
作者:郑燮
咬定青山不放松,立根原在破岩中。
千磨万击还坚劲,任尔东西南北风。

前言
又到了一年一度的南北人口大迁移的时候,没有买票的赶紧买票,今年很早就已经回家准备过年了,因为小编已经离职啦,最近正在积极复习找工作,闲话不多扯,开始今天的正题。
面试题目:如何在10亿个整数中找出前1000个最大的数。
这就是有名的TopN问题,这样的问题有很多种解法,下面我对我了解的解法做一个总结并写出最优算法。
如果初次听到这样的题目,我相信大家和我的第一反应都是一样的,先排序后输出前1000个,那么多排序,归并排序、快速排序、堆排序。。。
那么问题来了,排序的复杂度太大,数据量又是上亿级别的,明显排序方案不合理。那么我们能否不要全排,只排序部分元素,不就可以了吗?
方法一:冒泡排序
由此想到冒泡排序的原理:通过两层for循环,外层第一次循环找到数组中最大的元素放置在倒数第一个位置,第二次循环找到第二大的元素放置在倒数第二个位置。。。循环N次就可以找到TopN。
缺点:冒泡排序内层循环需要大量交换元素。复杂度介于O(n)和O(n^2)之间。
方法二:分而治之
由快速排序原理可知:选一个基准元素,每次排序可以将这个基准元素搁置在正确的位置,左边都是比基准小的元素,右边都是比基准大的元素从而将数组分成左右两部分,分而治之。TopN问题也同样如此,选择一个基准元素并通过快速排序将基准元素搁置在正确的位置,如果左边的元素个数小于1000,那么继续从基准右边排序,如果左边元素个数大于1000,那么从基准左边排序,直到基准的位置正好在1000,结束。
缺点:第一次排序复杂度是O(n),第二次排序复杂度是O(n/2),第三次排序复杂度是O(n/4)...
方法三:文件存储,分而治之
将比基准小的元素存储在txt1中,比基准大的文件存储在txt2中,然后通过类似方法二的形式,最后求出TopN。
缺点:磁盘读取,写入次数过多。
方法四:分布式、MapReduce
单机内存和性能确实受限,那么我们

最低0.47元/天 解锁文章
3608





