2020-02-08修改
前几天刷到一个视频漫画面试系列-如何在40亿个整数中寻找一个数字。作者只是给出了思路用bitmap判断,没有具体的代码实现。我自己思考了一下,给出解法:
教学视频
1 实现
1.1 Billion42.java
import java.util.HashSet;
import java.util.Set;
public class Billion42 {
private Set<Integer> set32_16, set24_16, set16_0;
Billion42() {
set32_16 = new HashSet<>();
set24_16 = new HashSet<>();
set16_0 = new HashSet<>();
}
public void add(int num) {
int val32_16, val24_16, val16_0;
val32_16 = (num & 0xFFFF0000);
val24_16 = (num & 0x00FFFF00);
val16_0 = (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) {
int val32_16, val24_16, val16_0;
val32_16 = (num & 0xFFFF0000);
val24_16 = (num & 0x00FFFF00);
val16_0 = (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个元素;
- int类型大小为4字节
所以一个set占用的内存大小为
65535 * 4 = 262140byte
然后再用set数量乘131070得到占用内容的大小
* 拆分的数量 * 4字节int * 65535
#32位整数
65535 * 4 * 3 = 393210byte = 767kb
#64位整数
65535 * 4 * 7 = 917490byte = 1791kb