极限挑战:40亿个非负整数中找到没有出现的数(bit数组)

软件求生 2024-08-09 10:04:20



大家好!我是小米,一个积极活泼、热爱分享技术的29岁程序员。今天,我们一起来探讨一个有趣且实用的算法问题:如何在40亿个非负整数中找到没有出现的数。这个问题不仅考验我们的算法设计能力,还需要我们巧妙地利用有限的内存资源。

问题背景

假设我们有40亿个非负整数,并希望找到其中一个没有出现的数。直接使用哈希表来保存所有出现过的数是不现实的,因为最坏情况下40亿个数都不相同,哈希表需要保存40亿条数据。每个32位整数需要4字节,那么40亿个整数大约需要16GB的空间,这显然超过了普通计算机的内存限制。

解决方案:Bit数组

为了节省内存,我们可以采用bit数组来解决这个问题。一个bit数组的每个位置可以存储一个二进制位(0或1),这样每个整数只需一个bit来表示是否出现过。由于bit数组的长度可以刚好覆盖所有可能的非负整数(0到4294967295),我们可以利用这点来设计我们的算法。

基本思路

申请bit数组:bit数组的大小为4294967296个bit,约为40亿bit。

空间换算:40亿bit / 8 = 5亿字节,约为0.5GB内存。

标记出现的数:遍历40亿个非负整数,遇到整数i,则将bit数组中下标为i的位置置为1。

查找未出现的数:遍历bit数组,找到第一个值为0的位置,该位置对应的整数就是没有出现的数。

代码实现

这段代码使用了一个byte数组来实现bit数组的功能,每个整数对应bit数组中的一个位。在主函数中,我们定义了一个示例的整数列表,并调用findMissingNumber方法来找到其中缺失的数。

进阶解法:内存限制为10MB

如果内存限制为10MB,我们无法直接申请一个大bit数组。此时,我们需要分块处理数据。假设10MB内存可以处理1千万字节的数据,即8千万bit,那么我们可以将40亿个整数分成若干个区间来逐一处理。

分块处理思路

第一遍统计:

将40亿个整数按区间划分,每个区间大小为8千万bit。

统计每个区间中数的个数,找到一个计数不足的区间。

第二遍处理:

针对找到的计数不足的区间,申请一个8千万bit的bit数组。

遍历40亿个整数,将落在该区间的整数映射到bit数组上。

查找未出现的数:

遍历bit数组,找到第一个值为0的位置,该位置对应的整数就是没有出现的数。

代码实现

END

通过这篇文章,我们学会了如何在有限内存条件下处理海量数据,找出未出现的整数。我们首先使用bit数组解决大规模数据的问题,然后进一步优化算法以适应更严格的内存限制。这不仅是算法设计中的一种重要技巧,也是实际工程中常见的挑战。

希望大家能从这篇文章中有所收获,继续热爱编程,享受解决问题的乐趣!我是小米,期待在下一篇技术分享中与大家再次相遇。祝大家编码愉快!

0 阅读:0