大数据算法->40亿个非负整数中找到出现两次的数和所有数的中位数

大数据算法->40亿个非负整数中找到出现两次的数和所有数的中位数

题目

原问题:

32位无符号整数的范围是0 ~ 4 294 967 295 现在有40亿个无符号整数, 可以使用最多1GB的内存,找出所有出现了两次的数.

补充问题

可以使用最多10MB的内存,怎么找到这40亿个整数的中位数?

解答

原问题

可以用bit map的方式来表示数出现的情况.具体地说,是申请一个长度为4 294 967 295 * 2的bit类型的数组Arr,用2个位置表示一个数出现的词频,1B占用8个bit,所以长度为4 294 967 295 * 2的bit类型数组占用1GB空间.

遍历这40亿个无符号数,如果初次遇到num,就把bitArr[num * 2 + 1]和bitArr[num * 2]分别设置为0和1,如果第二次遇
到num,就把bitArr[num * 2 + 1]和bitArr[num * 2]设置为1和0,如果第三次遇到num,就把bitArr[num * 2 + 1]和bitArr[num * 2]设置为1和1.以后再遇到num,发现此时bitArr[num * 2 + 1]和bitArr[num * 2]已经被设置为1和1,就不再做任何设置.遍历完成后,再依次遍历bitArr,如果发现bitArr[i * 2 + 1]和bitArr[i * 2]设置为1和0,那么i就是出现了两次的数.

补充问题

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

申请一个长度为2148的无符号整型数组arr[0…2147],arr[i]表示第i区间有多少个数.arr必然小于10MB.然后遍历亿个数,如果遍历到当前数为num,先看num落在哪个区间上<-(num/2M),然后将对应的进行arr[num/2M]++操作.这样遍历下来,就得到了每一个区间的数的出现情况,通过累加每隔区间的出现次数,就可以找到40亿个数的中位数(也就是20亿个数)到底落在哪个区间上.比如,0 ~ K-1区间上数的个数为19.998亿,但是发现当加上第K个区间上数的个数之后就超过了20亿,那么可以知道第20亿个数是第K区间上的数,并且可以知道第20亿个数是第K区间上的第0.002亿个数.

接下来申请一个长度为2MB的无符号整型数组countArr[0…2M-1],占用空间8MB.然后遍历40亿个数,此时只关心处在第K区间的数记为numi,其他的数省略,然后将countArr[numi-K*2M]++,也就是只对第K区间的数做频率统计.这次遍历完40亿个数之后,就得到了第K区间的词频统计结果countArr,最后只在第K个区间上找到第0.002亿个数即可.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值