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
題意:爬樓梯,每次走1步或者2步,走上n階的樓梯,有多少種走法。
- 方法一:暴力。O(2n)的時間複雜度,n=44過不去。
class Solution { public: int stairs[50] = {0, 1, 2}; int climbStairs(int n) { if (n <= 2) return n; else return climbStairs(n - 1) + climbStairs(n - 2); } };
-
方法二:記憶化搜索。memorization。因爲法一存在很多重複計算,導致時間太長,因此把一些已經求出來的解存進數組,不重複求解。時間空間都是O(n)。
執行用時 :0 ms, 在所有 C++ 提交中擊敗了100.00% 的用戶
內存消耗 :8.3 MB, 在所有 C++ 提交中擊敗了62.09%的用戶class Solution { public: int stairs[50] = {0, 1, 2}; int climbStairs(int n) { if (n <= 2) return n; else { if (stairs[n - 1] == 0) stairs[n - 1] = climbStairs(n - 1); if (stairs[n - 2] == 0) stairs[n - 2] = climbStairs(n - 2); return stairs[n - 1] + stairs[n - 2]; } } };
-
方法三:動態規劃。這個問題可以被分解爲一些包含最優子結構的子問題,即它的最優解可以從其子問題的最優解來有效地構建。第 i 階可以由以下兩種方法得到:
在第 (i−1) 階後向上爬 1 階。 在第 (i−2) 階後向上爬 2 階。
所以到達第 i 階的方法總數就是到第 (i−1) 階和第 (i-2) 階的方法數之和。令 dp[i] 表示能到達第 iii 階的方法總數:
dp[i]=dp[i−1]+dp[i−2]
。時間空間複雜度均爲O(n)。執行用時 :4 ms, 在所有 C++ 提交中擊敗了62.73% 的用戶
內存消耗 :8.4 MB, 在所有 C++ 提交中擊敗了54.70%的用戶class Solution { public: int climbStairs(int n) { if (n <= 2) return n; int *dp = new int[n + 1]; dp[1] = 1; dp[2] = 2; for (int i = 3; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; } };
-
方法四:斐波那契數列遞推。這個題實際上就是斐波拉契數列。只需使用兩個變量即可推出答案要求的解。時間O(n),空間O(1)。
Fib(n)=Fib(n−1)+Fib(n−2)
。現在我們必須找出以 1 和 2 作爲第一項和第二項的斐波那契數列中的第 n 個數,也就是說 Fib(1)=1 且 Fib(2)=2。
執行用時 :0 ms, 在所有 C++ 提交中擊敗了100.00% 的用戶
內存消耗 :8.3 MB, 在所有 C++ 提交中擊敗了70.59%的用戶class Solution { public: int climbStairs(int n) { if (n <= 2) return n; int first = 1, second = 2; for (int i = 3; i <= n; i++) { int third = first + second; first = second; second = third; } return second; } };
-
方法五:斐波拉契數列求解公式:
時間複雜度爲O(log(n)),用在快速冪上面了,空間O(1)。
執行用時 :4 ms, 在所有 C++ 提交中擊敗了62.73% 的用戶
內存消耗 :8.5 MB, 在所有 C++ 提交中擊敗了32.17%的用戶class Solution { public: int climbStairs(int n) { double sqrt5 = sqrt(5.0); double fibn = pow((1 + sqrt5) / 2, n + 1) - pow((1 - sqrt5) / 2, n + 1); return (int)(fibn / sqrt5); } };
-
方法六:Binets方法 :使用矩陣相乘。
solutions裏面分享的方法。