问题:
找出40亿个非负整数中未出现的数?
情况一:内存限制1GB
情况二:内存限制10MB
解答:
情况一:
40亿个无符号整数=4G*4B=16GB,远超内存。
BitMap方法:
(1)申请长度为40亿的bit类型的数组bitArr,标志该数是否出现,占用内存4G*1/8B=500MB,完全可以。
(2)遍历40亿个数,例如8000,则bitArr[8000]=1。
(3)遍历数组bitArr,标志为0的,即未出现的数。
情况二:
内存限制的很小,需分区间处理,对区间使用BitMap方法。
假设分成x个区间,则每个区间有4G/x个数,申请长度为4G/x个bit类型的数组,占用内存4G/x*4B/8<10MB,取占用8MB,即4G/x*4B/8=8MB,则x=64,即分成64个区间。
(1)第一次遍历
申请整形数组countArr[64],标志每个区间的计数,每个区间大小为n=2^24。
遍历40亿个数,根据当前数决定哪一个区间加1,如数A,A/n=10,则countArr[10]++;
再遍历countArr[i],若countArr[i]小于n,则第i区间必少数,即存在未出现的数。
(2)第二次遍历
申请bit型数组bitArr[n],假设第k区间少数。
遍历40亿个数,关注第k区间的数num,即num/n=k,将bitArr[num-n*k]=1;
再遍历bitArr[i],若bitArr[i]=0,则k*n+i即为未出现的数。