前几天刷到一个视频漫画面试系列-如何在40亿个整数中寻找一个数字。作者只是给出了思路用bitmap判断,没有具体的代码实现。我自己思考了一下,给出解法:
教学视频
import java.util.HashSet;
import java.util.Set;
public class Billion42 {
private Set set32_16, set24_16, set16_0;
Billion42() {
set32_16 = new HashSet<>();
set24_16 = new HashSet<>();
set16_0 = new HashSet<>();
}
public void add(int num) {
short val32_16, val24_16, val16_0;
val32_16 = (short) (num & 0xFFFF0000);
val24_16 = (short) (num & 0x00FFFF00);
val16_0 = (short) (num & 0x0000FFFF);
if (!(set32_16.contains(val32_16) &&
set24_16.contains(val24_16) &&
set16_0.contains(val16_0))) {
set32_16.add(val32_16);
set24_16.add(val24_16);
set16_0.add(val16_0);
}
}
public boolean isExists(int num) {
short val32_16, val24_16, val16_0;
val32_16 = (short) (num & 0xFFFF0000);
val24_16 = (short) (num & 0x00FFFF00);
val16_0 = (short) (num & 0x0000FFFF);
return (set32_16.contains(val32_16) &&
set24_16.contains(val24_16) &&
set16_0.contains(val16_0));
}
}
2.1 Billion42.java
public class main {
public static void main(String[] args) {
int rand = 0;
Billion42 bill = new Billion42();
for (long i = 0; i < 4294967295L; ++i) {
rand = (int) (Math.random() * (1073741823 - 0) + 0);
bill.add(rand);
}
int num = (int) (Math.random() * (1073741823 - 0) + 0);
//bill.add(num);
System.out.println(num);
//拆分32位整数后拆分后重新生成
System.out.println(
(num & 0xFFFF0000) | (num & 0x00FFFF00) | (num & 0x0000FFFF)
);
System.out.println(bill.isExists(num));
}
}
2 解题思路-使用位运算
将整数按16bit进行拆分,32位整数拆分为3个部份(64位整数拆分成7个部份),将这3个部份存储至3个set中。判断一个数字是否存在时判断该数字的所有bit位是否相同,从而来判断数字是否存在。
2.1 32位整数拆分方法//高位16bit (num & 0xFFFF0000) //中间位16bit (num & 0x00FFFF00) //低位16bit (num & 0x0000FFFF)2.2 64位整数拆分方法
(num & 0xFFFF000000000000) (num & 0x00FFFF0000000000) (num & 0x0000FFFF00000000) (num & 0x000000FFFF000000) (num & 0x00000000FFFF0000) (num & 0x0000000000FFFF00) (num & 0x000000000000FFFF)2.3 最大占用的内存大小
16bit的最大值为65536,因此每个set里元素最多只会有65535个元素;short类型大小为2字节
所以一个set占用的内存大小为
65535 * 2 = 131070byte
然后再用set数量乘131070得到占用内容的大小
* 拆分的数量 * 2字节short * 65535 #32位整数 65535 * 2 * 3 = 393210byte = 383kb #64位整数 65535 * 2 * 7 = 917490byte = 895kb



