我在最近的一次采访中遇到了这个问题:
你有一个范围为0 to 60000
的传入号码流,你有一个函数,它将从该范围获取一个数字并返回该数字的出现次数,直到那一刻。提供合适的数据结构/算法来实现该系统。
我的解决方案是:
创建一个大小为60001的数组,指向位向量。这些位向量将包含传入数字的计数,并且传入的数字也将用于索引相应数字的数组。随着计数变得太大而不能容纳它们,位向量将动态增加。
因此,如果数字的汇率为100numbers/sec
,那么,在1百万年内,总数将为= (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
,这将需要总共{{1}每个数字。
因此,假设4字节指针我们需要36 bits
内存用于数组,对于具有相同数字的情况,我们需要位向量大小= (60001 * 4)/1024 = 234 KB
,它仍然是大约234KB。而对于另一种情况,我们需要52/8 = 7.5 bytes
的位向量总计大约500KB。因此,用普通的PC和内存来做这件事是非常可行的。
但是面试官说,因为它是无限的流,它最终会溢出并给我提示,如果有很多PC我们怎么能这样做,我们可以在它们之间传递消息或考虑文件系统等。但我一直在想如果这个解决方案不起作用,那么其他人也会这样做。不用说,我没有得到这份工作。
如何用更少的内存来解决这个问题?你能想到另一种方法(使用PC网络)吗?
答案 0 :(得分:5)
问题的正式模型如下:
我们想知道它是否存在一个恒定的空间有界图灵机,这样在任何给定的时间内它都能识别所有夫妻的语言L(数量,到目前为止的出现次数)。这意味着所有正确的夫妇都将被接受,所有不正确的夫妻将被拒绝。
作为Hopcroft-Ullman中定理3.13的必然结果,我们知道恒定空间有界机器识别的每种语言都是常规的。
通过使用常规语言的抽取引理可以证明上述语言不是常规语言。所以你无法用恒定的空间有界机器识别它。
答案 1 :(得分:0)
你可以轻松地使用基于索引的搜索,通过使用像int arr [60000] [1]这样的数组,每当你得到一个数字,比如5000,直接访问索引(num-1)=(5000-1)as ,arr [num-1] [1],然后递增数字,现在每当你想知道特定数量有多少次,你就可以通过arr [num-1] [1]来访问它,你就可以了获得该数字的计数,其最简单的线性时间实现。
答案 2 :(得分:-1)
这不是External Sorting吗?将无限流存储在文件中。在文件中执行seek()(RandomAccessFile.seek()
)并获取相应的时间戳。这与二进制搜索类似,因为数据按时间戳排序。一旦达到适当的时间戳,问题就变成从一组无数的数字中计算一个特定的数字。在这里,由于数字范围有限,而不是在内存中进行快速排序,因此可以进行计数排序。