【每日一题】LeetCode. 70. 爬楼梯

每日一题,防止痴呆 = =

一、题目大意

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。
【每日一题】LeetCode. 70. 爬楼梯_第1张图片
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/climbing-stairs

二、题目思路以及AC代码

今天的每日一题是两年前做过的一道题 = =,也是一道比较经典的DP吧,下面我按照官解给出的多个思路的目的,一个个的说一下

思路一:动态规划

这个肯定是可以用动态规划求解的。我们令dp[i]表示爬i层台阶共有多少种方法,那么我们又知道每次只能爬1或2个台阶,那么dp[i] = dp[i-1] + dp[i-2],直接用DP解决即可,时间复杂度是O(n),然后我们发现其实这个DP只用到了三个数,所以空间复杂度就可以由O(n)优化到O(1)。

思路二:矩阵快速幂

我们发现,由上面提到的矩阵的递推公式可以得到以下公式:
在这里插入图片描述
也就是说,我知道了f(0)和f(1)之后,我们可以通过不断的乘一个固定的矩阵来得到想要的f(n),那其实就是一个求矩阵幂的问题,关于幂运算,我们是有快速幂的方法可以使得复杂度是O(logn)的,当然矩阵的乘法复杂度是O(1),然后空间复杂度也是O(1)。

思路三:直接用通项公式求解

这就是数学问题了,其实我们观察递推公式就可以发现,这个DP数组其实就是一个斐波那契数列,那么我们就可以直接求通项公式,然后将n带入求解,但这里面会涉及到浮点数精度的问题,而且由于通项公式中含有幂次,所以时间复杂度还是O(logn),空间复杂度是O(1)。

AC代码

这里只将思路一中的DP写一下,其实也就是在求斐波那契数列而已。

class Solution {
public:
    int climbStairs(int n) {
        if (n < 2) return 1;

        int first = 1;
        int second = 1;
        int third;
        
        for (int i=2;i<=n;i++) {
            third = first + second;
            first = second;
            second = third;
        }

        return third;
    }
};

如果有问题,欢迎大家指正!!!

你可能感兴趣的:(每日一题)