Kata:Hamming number

對影yu發表於2019-02-16

題目:求第n個Hamming numbers

Hamming number

$$H = 2^i * 3^j * 5^k$$

其中:

$$i, j, k >= 0$$

解這道題倒是不難,只要暴力迴圈就好了,只不過這樣挺蠢的,而且浪費資源也挺多的,所以也沒有通過測試。

我想著Hamming number如何預測某個數的2倍或者3、5倍在整體數列中的位置,想了半天都沒什麼頭緒。於是上網看了個解決方案,理解了下,思路大概是這樣的:

Hamming number數列是這樣的:

1,2,3,4,5,6,8,9,10,12,15,16……

觀察其中2的數列,有:

1,2×2,2×3,2×4,2×5,2×6,2×8……

可以發現Hamming number除以2以後仍然在該數列中,觀察可以得出數列第一個2的倍數,其實就是2乘以數列中的第一個數,第二個2的倍數是2乘以數列中的第二個數,後面的數字都是如此。也就是說如果我要求第5個2的倍數,就讓2乘以數列中第5個數。

同理,3、5的倍數也是如此。知道這個遞增關係,就可以儲存當前是第幾個倍數,方便計算下一個數。

按上面的思路,有下面這個演算法:

def hamming(limit):
    h = [1] * limit
    x2, x3, x5 = 2, 3, 5
    i = j = k = 0

    for n in range(1, limit):
        h[n] = min(x2, x3, x5)
        if x2 == h[n]:
            i += 1
            x2 = 2 * h[i]
        if x3 == h[n]:
            j += 1
            x3 = 3 * h[j]
        if x5 == h[n]:
            k += 1
            x5 = 5 * h[k]
    return h[-1]

相關文章