O(N) 速度和 O(1) 内存的汉明数

Hamming numbers for O(N) speed and O(1) memory

免责声明:关于它的问题很多,但我没有找到任何需要常量内存的问题。

海明数是一个数2^i*3^j*5^k,其中i,j,k是自然数。

有没有可能用O(N)时间和O(1)(常数)内存生成第N个海明数?在 generate 下,我指的是生成器,即你只能输出结果而不能读取之前生成的数字(在这种情况下内存将不是常量)。但是你可以保存一些常数。

我看到只有常量内存的最佳算法并不比 O(N log N) 好,例如,基于优先级队列。但是有数学证明不可能在O(N)时间内构造出一个算法吗?

这里首先要考虑的是直接切片枚举算法,例如可以看到in this SO answer,枚举序列成员给定对数值(base 2)附近的三元组(k,j,i),使得target - delta < k*log2_5 + j*log2_3 + i < target + delta,递进计算选择 jk 时的累积对数,以便直接知道 i

因此它是一个 N2/3-时间算法产生 N2/一次 3 宽的序列切片(k*log2_5 + j*log2_3 + i 接近目标值,所以这些三元组形成了 tetrahedron filled with the Hamming sequence 三元组的外壳 1),意思是每个产生的数 O(1) 次,因此在 [=38= 中产生 N 个序列成员]O(N) 摊销时间和O(N2/3) -space。这与基线 Dijkstra 算法没有任何改进 2 具有相同的复杂性,甚至 非摊销 和更好的常数因子。

要使其成为 O(1)-space,地壳宽度将需要随着我们沿着序列前进而变窄。但是地壳越窄,在枚举它的三元组时就会有越来越多的失误 -- 这几乎就是你要求的证明。恒定切片大小意味着 O(N2/3) 每个 O(1) 切片,对于总体 O(N5/3) 摊销时间,O(1) space算法。

这些是这个频谱的两个端点:从N1-时间,N2/3-space到N0space, N5/3-时间,摊销。


1 这里是 the image from Wikipedia,对数垂直刻度:

从侧面看,这本质上是一个由汉明序列三元组 (i,j,k) 在 space 中拉伸为 (i*log2, j*log3, k*log5) 的四面体。图片有点歪,要是真3D图就好了

edit: 2 看来我忘记了必须对切片进行排序,因为它们是由 j,k-枚举。这将通过切片算法按顺序生成序列的 N 数字的最佳复杂度更改为 O(N2/3 log N) 次,O(N2/3) space 并使 Dijkstra 算法成为赢家。它不会改变 O(N5/3) 时间的上限,因为 O(1) 片。