LeetCode系列记录我学习算法的过程。
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
题目
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例:
输入: n = 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
输入: n = 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
提示
1 <= n <= 45
思路
这个题目刚开始看确实没有想到什么好的思路,只想到了递归:
每次迈步只有两种情况,迈一步或两步,所以可以通过递归来遍历所有情况,当步数达标则停止该分支递归并记录一次,最后返回记录的次数
但是实际去提交执行后发现执行耗时超出限制😂,只能想其他的解法
这题是个简单难度的,所以按理来说不应该怎么难解,我把前几种可能的结果列了出来:1 2 3 5 8 13 21
这不就是小学还是初中学的找规律 f(x)=f(x−1)+f(x−2) 来着嘛😂
仔细分析了一下其中的规律,发现确实是有一些逻辑的,例如要到达三阶台阶,有两种情况:
- 在一阶的情况下迈
2步 - 在二阶的情况下迈
1步
那到达三阶的情况不就是 一阶所有情况 +2 加上 二阶所有情况 +1 嘛
想明白了其中的规律,那写起代码来就容易了
代码实现
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
// 一阶 或 二阶 直接返回结果
if (n === 1 || n === 2) return n
// res记录次数, a 初始为一阶情况 b 初始为二阶情况
let res = 0, a = 1, b = 2
// 从三阶开始进行遍历
for (let i = 3; i <= n; i++) {
// 当前阶次数 为 前两阶次数之和
res = a + b;
// 重置前两阶次数 为下次循环做准备
[a, b] = [b, res]
}
// 返回结果
return res
};
优化
将所有情况都考虑进来,可以简化一下代码
var climbStairs = function(n) {
let res = 0, a = 0, b = 1
for (let i = 1; i <= n; i++) {
res = a + b;
[a, b] = [b, res]
}
return res
};