1. 程式人生 > 實用技巧 >[劍指offer]跳臺階問題&動態規劃求解

[劍指offer]跳臺階問題&動態規劃求解

題目描述
一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。
示例1
輸入
1
返回值
1
示例2
輸入
4
返回值
5

遞迴的方式求解:
由於它可以跳1級臺階或者2級臺階,所以它上一步必定在第n-1,或者第n-2級臺階,也就是說它跳上n級臺階的跳法數是跳上n-1和跳上n-2級臺階的跳法數之和。

public class Solution {
    public int JumpFloor(int n) {
        if (n == 1) return 1; 
        if (n == 2) return 2;
        return JumpFloor(n - 1) + JumpFloor(n - 2);
    }
}

動態規劃的思想:
用於求最優化問題,將問題分為多個字問題分別求最優值,再求整個問題的最優值。解決問題的方法類似於分治法,而與分治法不同的是,動態規劃問題子問題的最優解不是互相獨立的,可以通過
若用分治法來解這類問題,則分解得到的子問題數目太多,有些子問題被重複計算了很多次。如果我們能夠儲存已解決的子問題的答案,而在需要時再找出已求得的答案,這樣就可以避免大量的重
復計算,節省時間。

動態規劃的問題分析:
青蛙要跳到第三層,有兩種情況:
1.先跳到第一層,剩下兩層有兩種跳法
2.先跳到第二層,剩下一層有一種跳法
把問題推廣到n層:
1.先調到1層,剩下n-1層設有pre1種跳法
2.先調到2層,剩下n-2層設有pre2種跳法
同時可以發現第 n 階的解法,只要用到 n - 1 和 n - 2 階是多少,其他的不用考慮,因此用兩個變數臨時存下來即可
dp(i) = dp(i-2) + dp(i-1)

public class Solution {
    public int JumpFloor(int target) {
        if(target <= 2){
            return target;
        }
        int pre2 = 1, pre1 = 2;
        for (int i = 3; i <= target; i++){
            int cur = pre2 + pre1;
            pre2 = pre1;
            pre1 = cur;
        }
        return pre1;
    }
}