「这是我参与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) 的结果,已经计算过的结果就不需要再次计算了。递归是一个至顶而下的过程,它讲的是逐步分解。而动态规划是一个至底向上的过程,以保证每一个子问题都只计算一遍
这一题的状态转移方程如下所示:
- 当
n <= 2时,f(n) = n - 当
n > 2时,f(n) = f(n-1) + f(n-2)
举个例子
此处以 n = 6 作为例子
- 初始化一维数组
dp[n+1](为了下标一致,舍弃dp[0]) - 赋值
dp[1] = 1,dp[2] = 2 - 开始遍历,从
i=3开始,dp[3] = dp[2] + dp[1] = 3 - 当
i = 4时,dp[4] = dp[3] + dp[2] = 5 - 当
i = 5时,dp[5] = dp[4] + dp[3] = 8 - 当
i = 6时,dp[6] = dp[5] + dp[4] = 13 - 返回结果
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);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~