leetcode 70climbing stairs 爬樓梯
阿新 • • 發佈:2018-12-31
題目要求(必會,高頻題)
有一個爬樓梯的任務。 需要n步才能達到頂。每次可以爬1或2步。 通過多少不同的方式登頂?
注意:給定n將是一個正整數。
示例
Example 1:
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
- 1 step + 1 step
- 2 steps
>Example 2:
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
- 1 step + 1 step + 1 step
- 1 step + 2 steps
- 2 steps + 1 step
解題思路
因為每次只能走一步或者兩步, 所以在到達n層之前只可能有兩種情況:在 n-1層走一步,或者n-2層走兩步。接著,我們繼續分析,到達n-1層和n-2層同樣也是隻有兩種方法,如此下去,我們可以發現這是一個遞迴問題。
(1) 所以第一種方法我們可以根據遞迴來進行解決。
class Solution {
public:
int climbStairs(int n) {
if(n==1||n== 2) return n;
else return (climbStairs(n-1) + climbStairs(n-2));
}
};
缺點 遞迴方法就是重複計算很多,導致耗時很長,時間成指數級增長,n較大時,可能會超出時間不會AC。
(2) 動態規劃思想解決(強推!!!)
爬樓梯數目其實是一個斐波拉契數列。
當一個問題可以分解成若干重複的子問題時,動態規劃的思想非常實用:
只需要將子問題求解一次,以後再遇到,直接呼叫。
關鍵是找到一個轉移方程,由於斐波拉契數列的特點(前兩項初值1,1。從第3項開始,每一項都等於前兩項之和
Fibonacci sequence
dp[i] = dp[i-1] + dp[i-2];
程式中陣列 dp[n+1] ,n為字元個數。
dp[i]表示的含義:以索引i結尾的子字串之和。
class Solution {
public:
int climbStairs(int n) {
int dp[n+1];
dp[0] = 1;
dp[1] = 1;
for(int i=2;i<n+1;++i)
dp[i] = dp[i-1] + dp[i-2];
return dp[n];
}
};