Python編程題26--爬樓梯

題目

假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個臺階。請問有多少種不同的方法可以爬到樓頂呢?

注意:給定 n 是一個正整數,其範圍爲:1 ≤ n ≤ 100。

例如:

給定一個正整數:2,返回結果:2

說明:共有 2 種方法爬到樓頂,第一種爲 1階 + 1階,第二種爲 2 階。

給定一個正整數:3,返回結果:3

說明:共有 3 種方法爬到樓頂,第一種爲 1階 + 1階 + 1階,第二種爲 1階 + 2階,第三種爲 2階 + 1階。

實現思路

分析上面題目,可以發現第 n 個臺階只能從第 n-1 個臺階或第 n-2 個臺階走上去,那麼就可以得到以下結論:

第 n 個臺階的走法 = 第 n-1 個臺階的走法 + 第 n-2 個臺階的走法

看到這裏,是不是感覺很熟悉,沒錯,這不就是 斐波那契數列 嘛,不同的地方在於我們這裏的第1項值是1,第二項值是2。那麼接下來應該就很簡單了,我們要做的就是求出 斐波那契數列 的第 n 項。

之前有寫過關於 斐波那契數列 的題目,可以前往瞭解:Python編程題9--斐波那契數列

代碼實現--非遞歸

def climbStairs(n):
    a, b = 1, 1
    while n > 1:
        a, b = b, a + b
        n -= 1
    return b

代碼實現--遞歸

def climbStairs(n):
    if n == 1 or n == 2:
        return n
    return climbStairs(n - 1) + climbStairs(n - 2)

如果在算法題中,當 n 的值比較小時,上面遞歸解法是沒什麼沒問題的,但如果 n 的值較大,比如上面的 n = 100 ,這個時候必然會提示超出時間限制。

return climbStairs(n - 1) + climbStairs(n - 2)

在上面代碼中,每次都需要2次遞歸,同時會出現大量的重複計算,隨着 n 的增大,導致耗時非常久,性能變得非常差,另外調用函數次數過多,也容易出現棧溢出。

因此,我們對遞歸代碼進行優化如下:

def climbStairs_recursive(n, first, second):
    if n == 1 or n == 2:
        return n
    elif n == 3:
        return first + second
    return climbStairs_recursive(n - 1, second, first + second)

def climbStairs(n):
    return climbStairs_recursive(n, 1, 2)

優化後的代碼中,我們每次只需要1次遞歸,並且直接通過 first、second 記錄當前相加的2個數值,避免了重複計算。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章