40亿个非负整数中找到出现两次的数和所有数的中位数

32位无符号整数的范围是0 ~ 4 294 967 295 现在有40亿个无符号整数,可以使用最多1GB的内存,找出所有出现了两次的数。
补充问题: 可以使用最多10MB的内存,怎么找到40亿个整数的中位数?

原问题: 可以用 bit map 来表示数出现的情况。

  1. 申请一个长度为 4 294 967 295 × 2 的bit类型的数组bitArr,1B占用8
    个bit,所以长度为 4 294 967 295 × 2 的bit类型的数组占用1GB空间,
    用2个位置表示一个数出现的词频。
  2. 怎么使用bitArr数组?遍历这40亿个无符号数。
    ① 如果第一次遇到num,就把 bitArr[num2] 和 bitArr[num2 + 1]
    设置为01;
    ② 如果第二次遇到num,就把 bitArr[num2] 和 bitArr[num2 + 1]
    设置为10;
    ③ 如果第三次遇到num,就把 bitArr[num2] 和 bitArr[num2 + 1]
    设置为11;
    ④ 以后再遇到num,发现 bitArr[num2] 和 bitArr[num2 + 1]已经
    被设置为11,就不再做任何设置。
  3. 再次遍历bitArr,如果发现bitArr[i2] 和 bitArr[i2 + 1]设置为10,那么
    i 就是出现了两次的数。

补充问题:分区间的方式处理。长度为2MB的无符号整型数组占用的空间为8MB,所以区间的数量定位 4 294 967 295 / 2M,向上取整2148个区间。第0个
区间 0 ~ 2M-1,第1个区间 2M ~ 4M - 1,第 i 个区间为2M × i ~ 2M
× (i+1) - 1,…

  1. 申请一个长度2148个无符号整型数组 arr[0…2147],arr[i] 表示第 i 个
    区间有多少个数。遍历40亿个数,看num落在哪个区间上(num/2M),
    然后arr[num/2M]++。
  2. 通过累加每个区间的出现次数,就可以找到40亿个数的中位数到底落在
    哪个区间。
    比如,0 ~ K - 1区间上数的个数为19.988亿,但是发现当加上第 K 个
    区间上数的个数之后就超过了 20亿,那么就可以知道第20亿个数是第
    K个区间上的数,并且可以知道第20亿个数是第 K 个区间上的第0.002
    亿个数。
  3. 接下来申请一个长度为 2MB的无符号整型数组 countArr[0…2M - 1]。
    再次遍历40亿个数,只对第 K 个区间上的数numk做词频统计 ,将
    countArr[numk - K*2M]++,最后在第 K 个区间找到第 0.002亿个数。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值