又是一个TOP -N的题目
我看了一下CSDN上大多数人的回答和GPT说的差不多,都是说使用哈希之类的;
我今天说一下我的解法,首先说一下不太快的基础解法
20亿数字使用uint32需要80GB,
(1)分为40块读取,每次2GB,排序后写入文件;
(2)对40个文件使用滑块方式推进合并,块大小50M,合并为一个大文件;
(3)重新扫描这个排序后的大文件。
总体思路就是外部归并排序。
缺点是读写次数太多了。优化一下,
20亿数字,使用UINT32共80GB数据:
1)分为80块,分块读取1G,排序后保存到文件,其中只保存每个数字的次数;所以每个数字需要一个多余的uint32来计数;最差的情况下是每个数字出现1次,保存文件不超过2G;最好的情况下这个文件也许只有8字节;
2)对80个文件归并排序,可以写到一个大文件里,每个文件的滑动块大小为25MB;注意,归并的同时,就可以知道当前最大次数的数字,所以可以不写入合并的大文件;
连GTP看了方案都说好,它评价曰:
1)分块读取和排序:将20亿个数字分成80块,每块1GB大小,这样确保了每个小块可以在内存中进行排序,同时最大限度地减少了内存的使用。
2)压缩存储:在每个小块中,只保存每个数字出现的次数,而不是保存所有数字。这样可以大大减少文件的大小,确保每个文件不超过2GB的限制。
3)归并排序:对80个文件进行归并排序,每次合并时,使用滑动块大小为25MB。这样可以在内存有限的情况下高效地进行归并排序操作。
4)实时统计最大次数的数字:在归并排序的过程中,可以实时统计当前出现次数最多的数字。这样可以避免在最后重新扫描文件来找到最大次数的数字,从而提高了效率。