【LeetCode】No.70 Climbing Stairs

【原题】

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?Note: Given n will be a positive integer.

【翻译】

爬楼梯时可以一次爬一层或者两层,问要到达第n层,有多少种方法?n为正整数。

【解题思路】

设爬上第n层楼梯有S(n)种方法,那么爬上第n-1层楼梯有S(n-1)种方法,再爬一层就到达第n层;爬上第n-2层楼梯有S(n-2)种方法,再爬两层就到达第n层;最后一步不一样,所以是两种不一样的方法,此时斐波那契数列派上用场了。S(n)=S(n-1)+S(n-2), n为正整数,其中S(1)=1, S(2)=2, S(3)=3, ......

(1)递归

两个递归调用,加法运算的次数仍然是斐波那契数列,导致时间复杂度呈指数级。结果超时。

class Solution {
public:
    int climbStairs(int n) {
        if (n==1||n==2)
            return n;
        else
            return climbStairs(n-1)+climbStairs(n-2);
    }
};

(2)迭代

做n-1次加法运算,没有必要特意使用一个数组来存储斐波那契数列中的前面元素,为了完成该任务,只需要存储两个元素就足够了。时间复杂度O(n),空间复杂度O(1)。

class Solution {
public:
    int climbStairs(int n) {
        int f[10000];
        f[1]=1;
        f[2]=2;
        for(int i=3; i<=n; i++){
            f[i]=f[i-1]+f[i-2];
        }
        return f[n];
    }
};

【其他解法】

(1)利用公式

class Solution {
public:
    int climbStairs(int n) {
        double s = sqrt(5);
        return floor((pow((1+s)/2, n+1) + pow((1-s)/2, n+1))/s + 0.5);
    }
};

(2)利用方阵的快速幂

基于等式:当n>=1时,,比如,.......

class Solution {
public:
    //Fibonacci数列
    int climbStairs(int n) {
        if(n == 0){
            return 0;
        }
        int A[2][2] = {1,1,1,0};
        //初始为单位矩阵
        int Matrix[2][2] = {1,0,1,0};
        //n = n - 1;
        for(; n ;n >>= 1){
            //奇偶
            if(n&1){
                MatrixMulti(Matrix,A);
            }//if
            MatrixMulti(A,A);
        }//for
        return Matrix[0][0];
    }
private:
    //矩阵乘法
    void MatrixMulti(int matrix[2][2],int matrix2[2][2]){
        int a = matrix[0][0] * matrix2[0][0] +  matrix[0][1] * matrix2[1][0];
        int b = matrix[0][0] * matrix2[0][1] +  matrix[0][1] * matrix2[1][1];
        int c = matrix[1][0] * matrix2[0][0] +  matrix[1][1] * matrix2[1][0];
        int d = matrix[1][0] * matrix2[0][1] +  matrix[1][1] * matrix2[1][1];
        matrix[0][0] = a;
        matrix[0][1] = b;
        matrix[1][0] = c;
        matrix[1][1] = d;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值