第二章:爬楼梯问题——斐波那契的现实应用

101 阅读2分钟

第二章:爬楼梯问题——斐波那契的现实应用

“爬楼梯问题”是面试中出现频率极高的题目之一,同时也是动态规划的绝佳练习案例。

一、题目描述

假设你正在爬一个共有 n 阶的楼梯。每次你可以爬 1 阶或 2 阶,请问有多少种方法可以爬到楼顶?

这个问题的实质是:从第 0 阶到第 n 阶,有多少种跳法。

二、分析与状态转移

1. 状态定义

dp[i] 表示爬到第 i 阶楼梯的方法总数。

2. 状态转移方程

由于每次只能从 i - 1i - 2 爬上来,所以有:

dp[i] = dp[i - 1] + dp[i - 2];

这和斐波那契数列的公式如出一辙。

3. 初始条件

dp[0] = 1; // 一种“什么都不做”的走法
dp[1] = 1; // 只能爬一阶的情况

三、实现代码

3.1 标准 DP 写法

function climbStairs(n) {
  const dp = new Array(n + 1).fill(0);
  dp[0] = 1;
  dp[1] = 1;
  for (let i = 2; i <= n; i++) {
    dp[i] = dp[i - 1] + dp[i - 2];
  }
  return dp[n];
}

3.2 空间优化写法

function climbStairs(n) {
  if (n <= 1) return 1;
  let a = 1,
    b = 1;
  for (let i = 2; i <= n; i++) {
    let sum = a + b;
    a = b;
    b = sum;
  }
  return b;
}

四、示例演算

n = 4 为例:

dp[0] = 1
  -> [ ]
dp[1] = 1
  -> [1]
dp[2] = dp[1] + dp[0] = 1 + 1 = 2
  -> [1,1], [2]
dp[3] = dp[2] + dp[1] = 2 + 1 = 3
  -> [1,1,1], [1,2], [2,1]
dp[4] = dp[3] + dp[2] = 3 + 2 = 5
  -> [1,1,1,1], [1,1,2], [1,2,1], [2,1,1], [2,2]

答案是 5 种。

五、小结

“爬楼梯问题”和斐波那契数列本质上是一样的,因此它非常适合用来理解:

  • 状态转移方程的构建方式
  • 动态规划的核心思想:将大问题拆解为子问题,并保存子问题的解以避免重复计算
  • 如何通过空间优化进一步提升性能

下一章,我们将进入一个稍微复杂一点的实际问题——打家劫舍问题(House Robber),学习如何在“不能选相邻元素”的约束下应用动态规划。