0070. Climbing Stairs - chasel2361/leetcode GitHub Wiki

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.

Example 1:
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

Example 2:
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

這其實是排列組合問題吧XDDDD

這個問題應該也可以用動態規劃來解

問題一:總共有幾個 2 跟 1 的組合

問題二:每個組合有幾種走法

這兩個問題合在一起就是最終的答案

首先,總共最多可以有 n//2 個 2 ,每少一個 2 就會多兩個 1

而每種組合的走法可以引用排列組合的"不盡相異物直線排列"理論,可以得知有r種n個物品時,這些物品共有 (n!/n_1!n_2!...n_r!) 種排列法

所以每組的走法有 n!/n_2!n_1! 種,總共的組數可以使用計數器來達成

[1] 先判斷輸入值是否被 2 整除
[2] 若否,計算走法時需要多加一個 1

class Solution:
    def climbStairs(self, n: int) -> int:
        num_2 = n // 2
        count = 0
        i = 0
        if n % 2 == 1:  # [1]
            while num_2 >= 0:
                up = self.factorial(num_2 + i*2 + 1)  # [2]
                do = self.factorial(num_2) * self.factorial(i*2 + 1)  # [2]
                count += (up / do)
                num_2 -= 1
                i += 1
        else:  # [1]
            while num_2 >= 0:
                up = self.factorial(num_2 + i*2)
                do = self.factorial(num_2) * self.factorial(i*2)
                count += (up / do)
                num_2 -= 1
                i += 1
        return int(count)
        
    def factorial(self, n):
        res = 1
        while n > 1:
            res *= n
            n -= 1
        return res

這個解法的時間複雜度是O(N),空間複雜度是O(1)


寫完之後發現雨蕭大大有更快的解法,他的概念是來看看能不能找到相互之間的關係

如果要走到第 n 階的話,就需要知道走到第 n - 1 階以及第 n - 2 階的組數 (因為只有一次走一階跟一次走兩階兩種走法) ,兩者相加即為答案。同樣的,要走到第 n - 1 階,就需要知道走到第 n - 2 階以及第 n - 3 階的組數。

以此類推,最後需要知道走到第 1 階以及第 2 階所需要的組數,其分別為 1 組及 2 組。

由此可知

走到第 3 階的組數 = 1 + 2 = 3

走到第 4 階的組數 = 3 + 2 = 5

[1] 使用 s1, s2 相互相加以減少記憶體需求

class Solution:
    def climbStairs(self, n: int) -> int:
        if n == 1:
            return 1
        if n == 2:
            return 2
            
        s1, s2 = 1, 2
        for _ in range(n - 2):
            s1, s2 = s2, s1 + s2  # [1]
        return s2

這個解法的時間複雜度依舊是O(N),但程式結構簡單很多,速度可以更快。空間複雜度是O(1)