LeetCode70、爬楼梯

106 阅读2分钟

LeetCode 系列记录我学习算法的过程。

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

题目

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

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

示例:

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



输入: n = 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 12. 1 阶 + 23. 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
};

image.png

优化

将所有情况都考虑进来,可以简化一下代码

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
};