力扣第七十题-爬楼梯

410 阅读2分钟

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

前言

力扣第七十题 爬楼梯 如下所示:

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

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

注意: 给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶

一、思路

这一题是一道非常经典的动态规划题目,如果你没有写过的话,我非常推荐你试一下!

这一题题目比较简单,我们可以很轻松的使用递归来实现,伪代码大致如下所示:

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

上面这段代码比较好理解,就是当 n > 2 时,f(n) = f(n-1) + f(n-2)

那么既然我们知道 f(n) 的结果是由 f(n-1)f(n-2) 构成的,那为什么不先计算 f(n-1)f(n-2) 的结果呢?

tips:算法的本质就是用有限的空间来换取时间

我们可以使用一个一维数组存储 f(n) 的结果,已经计算过的结果就不需要再次计算了。递归是一个至顶而下的过程,它讲的是逐步分解。而动态规划是一个至底向上的过程,以保证每一个子问题都只计算一遍

这一题的状态转移方程如下所示:

  1. n <= 2 时,f(n) = n
  2. n > 2 时,f(n) = f(n-1) + f(n-2)

举个例子

此处以 n = 6 作为例子

  1. 初始化一维数组 dp[n+1] (为了下标一致,舍弃 dp[0]
  2. 赋值 dp[1] = 1dp[2] = 2
  3. 开始遍历,从 i=3 开始,dp[3] = dp[2] + dp[1] = 3
  4. i = 4 时,dp[4] = dp[3] + dp[2] = 5
  5. i = 5 时,dp[5] = dp[4] + dp[3] = 8
  6. i = 6 时,dp[6] = dp[5] + dp[4] = 13
  7. 返回结果 13 即可

可以看出动态规划的时间复杂度为 o(N),相较于递归快了很多!

二、实现

实现代码

实现代码与思路中保持一致

    public int climbStairs(int n) {
        if (n < 3)
            return n;
        int[] dp = new int[n+1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i=3; i<=n; i++) {
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }

测试代码

    public static void main(String[] args) {
        new Number70().climbStairs(6);
    }

结果

image.png image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~