我在最近的一次采访中遇到了这个问题:
您有一个范围内的传入数字流,0 to 60000
并且您有一个函数将从该范围内获取一个数字并返回该数字的出现次数直到那一刻。给出一个合适的数据结构/算法来实现这个系统。
我的解决方案是:
制作一个指向位向量的大小为 60001 的数组。这些位向量将包含传入数字的计数,并且传入数字也将用于索引到相应数字的数组中。当计数变得太大而无法容纳时,位向量将动态增加。
因此,如果这些数字以一定的速度出现,100numbers/sec
那么 100 万年后的总数将是 = (100*3600*24)*365*1000000 = 3.2*10^15
。在最坏的情况下,流中的所有数字都相同,ceil((log(3.2*10^15) / log 2) )= 52bits
并且如果数字均匀分布,我们将有(3.2*10^15) / 60001 = 5.33*10^10
每个数字的出现次数,这将需要36 bits
每个数字的总数。因此,假设 4 字节指针我们需要(60001 * 4)/1024 = 234 KB
用于数组的内存,并且对于具有相同数字的情况,我们需要位向量大小 =52/8 = 7.5 bytes
仍然在 234KB 左右。而对于另一种情况,我们需要(60001 * 36 / 8)/1024 = 263.7 KB
总计约 500KB 的位向量。所以,用普通的PC和内存来做这件事是非常可行的。
但面试官说,因为它是无限流,它最终会溢出,并给我提示,如果有很多 PC,我们怎么能做到这一点,我们可以在它们之间传递消息或考虑文件系统等。但我一直在想这个解决方案是否那时不工作,其他人也会。不用说,我没有得到这份工作。
如何用更少的内存来解决这个问题?你能想到另一种方法吗(可能是使用网络PC)?