只用2GB内存在20亿个整数中找到出现次数最多的数

有一个包含20亿个全是32位整数的大文件,在其中找到出现次数最多的数。
要求: 内存限制2GB。
初级进阶: 40亿个整数。
高级进阶: 80亿个整数。

常规思路:
  在很多整数中找到出现次数最多的数,通常的做法是使用哈希表对出现的每一个数做词频统计。如果一个数字出现20亿次,哈希表的一条记录需要8B。如果20亿个数都不同,那么哈希表的20亿条记录需要16GB。

解决思路:
  记录大概 2 亿多条不同的记录,2 亿多条不同的记录,大概1.6GB 的内存。我们可以把这 20 亿个数存放在不同的文件,然后再来筛选。例如,在 0 至 2 亿之间的放在文件1中,在 2 亿至 4 亿之间的放在文件2中….,由于 int 型整数大概有 42 亿个不同的数,所以我可以把他们映射到 21 个文件中去,如图:
在这里插入图片描述

显然,相同的数一定会在同一个文件中,我们这个时候就可以统计每个文件中出现次数最多的数,然后再从这些数中再次选出最多的数。

如果这 20 亿个数数值比较集中的话,怎么优化?
  如果给的这 20 亿个数数值比较集中的话,可以先把每个数先做哈希函数映射,根据哈希函数得到的哈希值,再把他们存放到对应的文件中,如果哈希函数设计到好的话,那么这些数就会分布的比较平均。

初级进阶: 可以加大文件的数量(映射到42个文件)。
如果给的这 40 亿个数中数值都是一样的,那么哈希表中,某个 key 的 value
存放的数值就会是 40 亿,然而 int 的最大数值是 21 亿左右,那么就会出现溢出,该怎么办?

(把 int 改为 long 会占用更多的内存),可以把 value 初始值赋值为 负21亿,这样,如果 value 的数值是 21 亿的话,就代表某个 key 出现了 42 亿次了。

高级进阶:可以一边遍历一遍判断,如果在统计的过程中,发现某个 key 出现的次数超过了 40 亿次,那么,就不可能再有另外一个 key 出现的次数比它多了,那我直接把这个 key 返回就搞定了。

常规套路:把一个大的集合通过哈希函数分配到多台机器中,或者分配到多个文件里,但是到底分配多少台机器、分配到多少文件,在解题时一定要确定下来。
参考网站:网站链接

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值