【LeetCode】70. 爬樓梯

問題描述

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note: Given n will be a positive integer.

你正在爬樓梯。需要n步才能到達頂端。
每次你可以爬1或2級臺階。你可以用多少種不同的方式爬到山頂?
注意:給定n是一個正整數。

例子1:

輸入: 2
輸出: 2
期待結果: 存在兩種方式爬到最頂端
    1. 1 步 + 1 步
    2. 2 步

例子2:

輸入: 3
輸出: 3
期待結果: 存在三種方式爬到最頂端
    1. 1 步 + 1 步 + 1 步
    2. 1 步 + 2 步
    3. 2 步 + 1 步

Python 實現

其實這是一個很經典的算法題,乍看之下不知道從何下手,但我們可以換個角度來看:從結果出發

根據題目可知,每次行動只有兩種可能,要麼爬 1 級臺階,要麼爬 2 級臺階,所以我們可以這麼來思考:假設到達第 n 個臺階共有 f(n) 種方式,則

  • 到達第 n 個臺階,要麼從 第 n-1 個臺階爬 1 級臺階到達,要麼從 第 n-2 個臺階爬 2 級臺階到達。到達第 n-1 個臺階共有 f(n-1) 種方式,到達第 n-2 個臺階共有 f(n-2) 種方式,所以 f(n) = f(n-1) + f(n-2);
  • 到達第 n-1 個臺階,要麼從 第 n-2 個臺階爬 1 級臺階到達,要麼從 第 n-3 個臺階爬 2 級臺階到達。到達第 n-2 個臺階共有 f(n-2) 種方式,到達第 n-3 個臺階共有 f(n-3) 種方式,所以 f(n-1) = f(n-2) + f(n-3);
  • 。。。

顯然,這個問題的答案就是一個斐波拉契數列了。斐波拉契數列的表達式:f(n) = f(n-1) + f(n-2)。

在該問題中,兩個基礎條件是 f(2) = 2,f(1) = 1。

因此,最後代碼實現一個斐波拉契數列就可以了。

 

實現一:遞歸實現

這種實現方式很直觀,但是有經驗的朋友都知道,在這個過程中,有些結果被重複計算,浪費的計算資源。例如

  • f(n) = f(n-1) + f(n-2)
  • f(n-1) = f(n-2) + f(n-3)

在這裏 f(n-2) 就被重複計算了兩遍。不僅如此,當 n 的值特別大的時候,使用遞歸實現很可能因爲函數調用次數過多,從而導致棧溢出。因此,實現斐波拉契數列常常使用下面第二種方法。

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """

        if n == 1:
            return 1
        if n == 2:
            return 2
        
        # May be stack overloaded.
        return self.climbStairs(n-1) + self.climbStairs(n-2)

 

實現二:數組(列表)實現

斐波拉契數列實際上從 1 到 n 分別對應一個結果值,因此使用數組或者列表來記錄結果最直觀。

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        
        if n == 1:
            return 1
        if n == 2:
            return 2

        F = [1, 2]
        for i in range(n-2):
            F.append(F[-1] + F[-2])
        return F[-1]

 

實現三:直接獲取結果

同樣是斐波拉契數列的一種實現形式,由於我們只需要獲取值爲 n 時的結果,因此通過分析得到基礎條件的值(f(2) = 2, f(1) = 1)之後,我們可以直接通過斐波拉契數列的計算公式,算出最後 f(n) 的值返回即可,這樣就可以避免使用數組或者列表記錄中間值,以節省內存空間。

class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
     
        if n == 1:
            return 1
        if n == 2:
            return 2

        s = 0
        a = 2
        b = 1
        for i in range(n-2):
            s = a + b
            b = a
            a = s
            
        return s
        

 

鏈接:https://leetcode.com/problems/climbing-stairs/

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