1. 程式人生 > 其它 >70.爬樓梯

70.爬樓梯

題幹

假設你正在爬樓梯。需要 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 階

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/climbing-stairs
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

思路分析

1.我們知道當爬一節樓梯的時候只有一種方法,即從0到1,跨一步;

2.爬2階樓梯有兩種方法,從0一次爬到2層,跨兩步;從1一次爬到2層,爬一步;

3.因為我們可選步數為1步或者2步,所以當我們距離終點前1步和前2步的時候,都各只有一種方式到達(差一步跨一步,差兩步跨2步(如果跨1+1,就會和差一步相同))

4.所以我們跨到目標的方法=我們跨到目標前1步的方法+跨到目標前2步的跨法。即f(n)=f(n-1)+f(n-2) (n.> 2)

程式碼編寫:

基於上述思路,可得:

class Solution {
    public int climbStairs(int n) {    
        return dp(n);
        }
        public int dp(int n){
            //前兩節臺階比較特殊,單獨列出
            if(n==1) return 1;
            if(n==2) return 2;
            //定義一個數組,存放前兩階的情況
            int[] count=new int[n];
            count[0]=1;
            count[1]=2;
//N>2時,按照F(n)=F(n-1)+F(n-2)疊加賦值
             for(int i=2;i<n;i++){
                 count[i]=count[i-1]+count[i-2];
             } 
//因為陣列從0開始,所以返回索引為n-1位
             return count[n-1];

        
           
    }
}
提交時間提交結果執行時間記憶體消耗語言
3 小時前通過0 ms35.5 MB

優化

參考的這個文章,寫的非常清晰明確,毫無基礎也可以看懂呢:https://mp.weixin.qq.com/s/3h9iqU4rdH3EIy5m6AzXsg

儲存時,有太多重複值。

所以根據雜湊表儲存,以時間換空間

class Solution {
    public int climbStairs(int n) {    
        return dp(n);
        }
        public int dp(int n){
            if(n==1) return 1;
            if(n==2) return 2;

            int[] count=new int[n];

            count[0]=1;
            count[1]=2;


            // 備忘錄演算法(利用HashMap儲存,)
            HashMap<Integer,Integer> map =new HashMap<>();
            if(map.containsValue(n)){
                return map.get(n);
            }

            else{
                int value=dp(n-1)+dp(n-2);
                map.put(n,value);
                return value;
            }

        
           
    }
}

但在leetcode裡,時間超出了,借鑑思路即可(遇到重複值的儲存遍歷時可用雜湊)。

動態規劃

class Solution {
    public int climbStairs(int n) {    
        return dp(n);
        }
        public int dp(int n){
            if(n==1) return 1;
            if(n==2) return 2;

            // 動態規劃
            int a=1;
            int b=2;
            int temp=0;
            for(int i=2;i<n;i++){
                temp=a+b;
                a=b;
                b=temp;
            } 
             return temp;
           
    }
}

利用三個變數互相迭代更新,反正最終我們需要知道f(n)=f(n-1)+f(n-2) (n.> 2) ,也就是說,我們最後只要保留f(n),f(n-1),f(n-2) ,前面的值迭代替換掉,對我們輸出最終結果沒有影響。

同時,我們空間中只申請了3個變數a,b,temp,空間複雜度是O(1),時間上需要對取決於n的值,為o(n)。

提交時間提交結果執行時間記憶體消耗語言
幾秒前通過0 ms35.2 MB