超大规模数据场景的问题(算法村第十五关黄金挑战)

对20GB文件进行排序

假设你有一个20GB的文件,每行一个字符串,请说明如何对这个文件进行排序?

这里给出大小是20GB,其实面试官就在暗示你不要将所有的文件都装入到内存里,因此我们只能将文件划分成一些块,每块大小是 x MB,x就是可用内存的大小,例如1GB一块,那我们就可以将文件分为20块。

先对每块进行排序,然后再逐步合并。这时候我们可以使用两两归并,也可以使用堆排序将其逐步合并成一个(先构造好大/小顶堆,在逐一输出堆顶元素)。堆排序也称为外部排序。

从10亿数字中寻找最小的100万个数字

设计一个算法,给定一个10亿个数字,找出最小的100万个的数字。假定计算机内存足以容纳全部10亿个数字。

方法一:先排序所有元素,然后取出前100万个数。该方法的时间复杂度为O(nlogn)。很明显对于10亿级别的数据,这么做时间和空间代价太高。

方法二:选择。首先遍历10亿个数字找最小,然后再遍历一次找第二小,然后再一次找第三小,直到找到第100万个。时间复杂度O(nm),也就是要执行10亿*100万次,这个效率一般的服务器都达不到。

方法三:大顶堆,“查小用大堆,查大用小堆”。

首先,为前100万个数字创建一个大顶堆,最大元素位于堆顶。然后遍历整个序列,只有比堆顶元素小的才允许插入堆中,并删除原堆的最大元素。之后继续遍历剩下的数字,最后剩下的就是最小的100万个。

时间代价是:遍历一次10亿个数字+更新堆的代价O(nlogn),勉强能够接受。堆占用的空间是100万Byte*4,大约为4MB。如果将10亿数字换成流数据,几乎只能用堆来做。

你可能感兴趣的:(算法村,算法,java,数据结构)