Easy!
題目描述:
假設你正在爬樓梯。需要 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 步
解題思路:
這道題目實際上跟斐波那契數列非常相似,假設梯子有n層,那么如何爬到第n層呢,因為每次只能爬1或2步,那么爬到第n層的方法要么是從第n-1層一步上來的,要不就是從n-2層2步上來的,所以遞推公式非常容易的就得出了:dp[n] = dp[n-1] + dp[n-2]。 由於斐波那契額數列的求解可以用遞歸,所以最先嘗試了遞歸,拿到OJ上運行,顯示Time Limit Exceeded,就是說運行時間超了,因為遞歸計算了很多分支,效率很低,這里需要用動態規划 (Dynamic Programming) 來提高效率,代碼如下:
C++解法一:
1 class Solution { 2 public: 3 int climbStairs(int n) { 4 if (n <= 1) return 1; 5 vector<int> dp(n); 6 dp[0] = 1; dp[1] = 2; 7 for (int i = 2; i < n; ++i) { 8 dp[i] = dp[i - 1] + dp[i - 2]; 9 } 10 return dp.back(); 11 } 12 };
我們可以對空間進行進一步優化,我們只用兩個整型變量a和b來存儲過程值,首先將a+b的值賦給b,然后a賦值為原來的b,所以應該賦值為b-a即可。這樣就模擬了上面累加的過程,而不用存儲所有的值。
C++解法二:
1 class Solution { 2 public: 3 int climbStairs(int n) { 4 int a = 1, b = 1; 5 while (n--) { 6 b += a; 7 a = b - a; 8 } 9 return a; 10 } 11 };