爬楼梯
- https://leetcode.cn/problems/climbing-stairs/
描述
- 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
- 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
提示
- 1 <= n <= 45
算法实现
1 )方案 1
function climbStairs(n: number): number {
// n为1的情况
if(n < 2) {
return 1
}
let dp: number[] = [1,1]; // 初始化工具
for(let i:number = 2; i <= n; ++ i) {
dp[i] = dp[i-1] + dp[i-2]
}
return dp[n]
}
-
思路
- 爬到第n阶可以在n-1阶爬1个台阶,或在n-2阶爬两个台阶
-
F(n) = F(n-1) + F(n-2)
- F(n) 代表n个台阶一共有多少种方法爬上去
- 爬到第n阶方法数量 = 爬到n-1阶方法数量 + 爬到n-2阶方法数量
- 一个问题可以分解为两个相互重叠的子问题,用动态规划解题
-
步骤
- 定义子问题:F(n) = F(n-1) + F(n-2)
- 反复执行子问题:从2 ~ n, 执行上述公式
- 这里的2,必须保证n-2是正的,如果只有1个台阶只有一个方法,而且1-2=-1,台阶数量不能为负数
-
注意
- dp 数组用来记录,第n阶需要多少种方法,下标为0的位置(0阶,当然n不能为0)设置成1
- 下标为1的位置,1阶是1,为什么把下标为0的位置设置1,因为它能帮助方便求得2阶,真实情况下n不会等于0,此处需要的是工具值
2 )方案 2
function climbStairs(n: number): number {
// n为1的情况
if(n < 2) {
return 1;
}
// 用两个变量来代表前两步
let dp0 = 1;
let dp1 = 1;
for(let i: number = 2; i <= n; ++ i) {
// 不断地把dp0, dp1分别代表数组的倒数两个数字
let tmp = dp0;
dp0 = dp1;
dp1 += tmp; // 用常量取代数组,空间复杂度下降
}
return dp1;
}
- 思路同上,优化了空间复杂度,官方给的滚动数组初始化的一些变量不太好理解,后面的矩阵快速幂方法比较复杂了,通项公式法就是用的数学推导
版权声明:本文为Tyro_java原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。