題目
假設你正在爬樓梯。需要 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個數值,避免了重復計算。
更多Python編程題,等你來挑戰:Python編程題匯總(持續更新中……)