[LeetCode]70.爬楼梯

在这里插入图片描述

解法一 动态规化

假设 f ( x ) f(x) f(x)为爬到第x层台阶时的方法数,通过举例观察可知:

f(1)f(2)f(3)f(4)
1234

f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n) = f (n-1) + f(n-2) f(n)=f(n1)+f(n2)
所以可以使用动态规化求解:

class Solution {
    public int climbStairs(int n) {
        if(n==1)return 1;
        int[] dp = new int[n];
        //初始化f(1)f(2)
        dp[0] = 1; dp[1]=2;
        for(int i = 2; i < n; i++){
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n-1];
    }
}

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)
通过观察可知 f ( n ) f(n) f(n)只跟之前两个状态有关因此可以滚动数组进一步优化空间复杂度为 O ( 1 ) O(1) O(1)

class Solution {
    public int climbStairs(int n) {
        if(n==1)return 1;
        if(n==2)return 2;
        //初始化p,q,r
        int p = 1, q = 2, r = 3;
        for(int i = 3; i < n; i++){
            p = q;
            q = r;
            r = p + q;
        }
        return r;
    }
}

解法二 通项公式的矩阵形式

在这里插入图片描述
通过通项公式可以把该问题转化为求矩阵幂,最后求解的答案为m11

class Solution {
    public int climbStairs(int n) {
        int[][] M ={{0,1},{1,1}};
        int[][] res = pow(M,n);
        return res[1][1];
    }

    //二分法求矩阵n次幂
    public int[][] pow(int[][] a,int n){
        int[][] ret={{1,0},{0,1}};
        while(n>0){
            if((n & 1) == 1){
                ret = multiply(ret,a);
            }
            n>>=1;
            a = multiply(a,a);
        }
        return ret;
    }

    //实现2*2矩阵乘法
    public int[][] multiply(int[][] a, int[][] b) {
        int[][] c = new int[2][2];
        for(int i = 0; i < 2; i++){
            for(int j = 0; j < 2; j++){
                c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j]; 
            }
        }
        return c;
    }
}
posted @ 2020-06-13 19:08  消灭猕猴桃  阅读(80)  评论(0编辑  收藏  举报