1.題目描述
假設你正在爬樓梯。需要 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 階
2.思路
這是一個簡單的動態規劃算法題。
F(1) = 1;
F(2) = 2;
F(3) = F(1)+F(2);
…
F(n) = F(n-1)+F(n-2);
由以上公式歸納,初次想到使用遞歸去解,即第n階樓梯的爬法等於第n-1階樓梯的爬法加上第n-2階樓梯的爬法。
3.解法
public int climbStairs(int n) {
if(n==1)return 1;
if(n==2)return 2;
return climbStairs(n-1)+climbStairs(n-2);
}
以上解法耗時較長,在提交時顯示超時了。
因爲
F(n) = F(n-1)+F(n-2)
=F(n-2)+F(n-3)+F(n-3)+F(n-4) = F(n-2)+2F(n-3)+F(n-4)
=F(n-3)+F(n-4)+2(F(n-4)+F(n-5))+F(n-5)+F(n-6) = F(n-3)+3F(n-4)+3F(n-5)+F(n-6)
= …
那麼我們需要想辦法利用一下中間值,因爲有部分相同的數值計算了多次。時間複雜度爲
考慮第 i 級階梯,第i級可以由第i-1階走1步上來,也可以由第i-2階走2步上來。
所以,新的解法爲:
public int climbStairs(int n) {
if(n==1)return 1;
if(n==2)return 2;
//return climbStairs(n-1)+climbStairs(n-2);
int[] temResult = new int[n];
temResult[0]=1;temResult[1]=2;
for(int i=2;i<n;i++){
temResult[i] = temResult[i-1]+temResult[i-2];
}
return temResult[n-1];
}
動態規劃問題
動態規劃原理
1.確認原問題與子問題
原問題爲球n階臺階所有走法的數量,子問題是求1階臺階、2階臺階、…n -1階臺階的走法。
2.確認狀態,本地的動態規劃狀態單一,第 i 個狀態即爲 i 階臺階的所有走法的數量。
3.確認邊界狀態的值。邊界狀態爲1階臺階與2階臺階的走法,1階臺階有1種走法,2階臺階有2種走法,即 dp[1] = 1,dp[2] = 2.
4.確認狀態轉移方程。將求第 i 個狀態的值轉移爲球第 i -1 個狀態的值與第 i-2個狀態的只,動態規劃轉移方程,
F(n) = F(n-1)+F(n-2);(n > 2)