【递归与迭代大对决】爬楼梯问题 JS+Python 双解,性能全面比较!

66 阅读2分钟

🧠 引言

“爬楼梯问题”堪称算法界的“Hello World”:

一次可以爬 1 级或 2 级楼梯,问爬到第 n 层有多少种不同的方法?

这道题表面简单,但它却是递归、动态规划与性能优化的完美训练场。

本篇我们将通过 递归 + 迭代 + 记忆化 三种方式,分别用 JavaScript 和 Python 编写,并对比它们的执行效率与易错点


📌 一、问题定义

输入:n = 5
输出:8

解释:
1-1-1-1-1  
1-1-1-2  
1-1-2-1  
1-2-1-1  
2-1-1-1  
2-2-1  
2-1-2  
1-2-2

这是一个 斐波那契型问题

f(n) = f(n - 1) + f(n - 2)

🧱 二、递归解法(暴力)

✅ JavaScript

function climbStairs(n) {
  if (n <= 2) return n;
  return climbStairs(n - 1) + climbStairs(n - 2);
}

console.log(climbStairs(5)); // 输出 8

✅ Python

def climb_stairs(n):
    if n <= 2:
        return n
    return climb_stairs(n - 1) + climb_stairs(n - 2)

print(climb_stairs(5))  # 输出 8

⛔ 缺点:时间复杂度为 O(2^n)指数级爆炸!


⚡ 三、记忆化递归优化(Top-down)

✅ JavaScript

function climbStairsMemo(n, memo = {}) {
  if (n <= 2) return n;
  if (memo[n]) return memo[n];
  memo[n] = climbStairsMemo(n - 1, memo) + climbStairsMemo(n - 2, memo);
  return memo[n];
}

console.log(climbStairsMemo(35)); // 快速输出 14930352

✅ Python

def climb_stairs_memo(n, memo={}):
    if n <= 2:
        return n
    if n in memo:
        return memo[n]
    memo[n] = climb_stairs_memo(n - 1, memo) + climb_stairs_memo(n - 2, memo)
    return memo[n]

print(climb_stairs_memo(35))  # 快速输出 14930352

✅ 时间复杂度优化到 O(n),空间也只用 O(n)


🚀 四、迭代解法(Bottom-up)

✅ JavaScript

function climbStairsIter(n) {
  if (n <= 2) return n;
  let first = 1, second = 2;
  for (let i = 3; i <= n; i++) {
    [first, second] = [second, first + second];
  }
  return second;
}

console.log(climbStairsIter(35)); // 输出 14930352

✅ Python

def climb_stairs_iter(n):
    if n <= 2:
        return n
    first, second = 1, 2
    for _ in range(3, n + 1):
        first, second = second, first + second
    return second

print(climb_stairs_iter(35))  # 输出 14930352

✅ 时间复杂度:O(n)
✅ 空间复杂度:O(1)最优解


🧪 五、三种解法性能对比

解法方式时间复杂度空间复杂度是否推荐备注
普通递归O(2^n)O(n)超时严重,仅适合教学
记忆化递归O(n)O(n)简洁、易理解
迭代(滚动数组)O(n)O(1)✅✅企业级标准写法

⚠️ 六、常见错误提醒

问题正确写法
忘记终止条件if (n <= 2) return n
Python memo 默认参数陷阱函数外定义 memo,或用 @lru_cache
忘记返回缓存结果return memo[n]

🧩 七、拓展任务

  • 支持“每次可以跳 1、2、3级”的爬楼梯变种
  • @lru_cache 写递归版本(Python)
  • 用尾递归优化(语言支持的情况下)

📚 总结一句话

在性能面前,递归和迭代都不是死敌,而是你算法思维灵活度的体现!


下一篇预告:

📘 第10篇:【用栈解决括号匹配问题】JS 与 Python 解锁面试常客题!