40亿个数中找一个数?1GB内存足够,这个算法绝了!
在大数据处理场景中,经常会遇到这样的问题:给定40亿个不重复的unsigned int
整数(范围0~4294967295),内存限制1GB,如何快速判断一个数是否存在于其中?
传统方法如哈希表、排序搜索等在空间或时间上都难以满足要求,而**位图算法(Bit Map)**却能轻松破解这个难题,用仅512MB内存实现O(1)时间复杂度的查询!
一、为什么传统方法行不通?
先算笔账:
- unsigned int占4字节,40亿个数需至少16GB内存(40亿×4字节=160亿字节≈15GB),远超1GB限制。
- 哈希表:除存储数据外还需额外哈希桶空间,内存占用更大,且实现复杂。
- 排序+二分查找:需先排序(耗时且内存不足),单次查询O(logN),效率不如O(1)。
核心矛盾:如何用有限内存表示42亿个可能的整数?位图算法给出了答案。
二、位图算法:用“位”代替“字节”的魔法
1. 原理:1位表示一个数的存在性
- unsigned int有42.9亿个可能值,每个值用**1位(bit)**标记是否存在:
- 存在→对应位置1,不存在→置0。
- 总位数:42.9亿位≈512MB(1字节=8位,512MB=536,870,912字节=4,294,967,296位),刚好在1GB内存限制内。
2. 类比理解:给每个数发一张“二进制门票”
想象有42亿个座位(对应0~4294967295),每个座位有一个开关(1位):
- 当数x存在时,按下x号座位的开关(置1);
- 查询时,看x号座位的开关是否打开(是否为1)。
而“座位”被分组,每8个座位组成一个“字节抽屉”(共512MB个抽屉),通过简单计算就能定位到具体座位。
三、3步实现:从数据填充到快速查询
步骤1:初始化512MB的“二进制画布”
创建一个长度为2^29
的unsigned char
数组(每个元素8位)ÿ