Skip to content

爬楼梯问题

问题描述

假设你正在爬楼梯,需要爬 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

方法思路

这是一个经典的动态规划问题,类似于斐波那契数列。关键点在于:

  • 到达第 n 阶楼梯的方法数等于到达第 n-1 阶和第 n-2 阶方法数之和。
  • 状态转移方程: dp[n] = dp[n-1] + dp[n-2]
  • 初始条件:
    • dp[1] = 1(爬 1 阶)
    • dp[2] = 2(爬 2 阶或两次 1 阶)

使用迭代代替递归以避免重复计算,优化空间复杂度至 (O(1))。


算法实现

java
class Solution {
    public int climbStairs(int n) {
        if (n <= 2) return n; // 直接返回 n=1 或 n=2 的结果
        int a = 1, b = 2;
        for (int i = 3; i <= n; i++) {
            int next = a + b; // 计算当前阶数的方法数
            a = b;           // 更新前两阶的状态
            b = next;        // 更新前一阶的状态
        }
        return b;
    }
}

时间复杂度: (O(n)),遍历一次从 3 到 n
空间复杂度: (O(1)),仅使用常数变量。


示例计算

n = 5 为例:

  1. 初始: a = 1(dp[1]),b = 2(dp[2])
  2. i=3: next = 1 + 2 = 3a = 2, b = 3
  3. i=4: next = 2 + 3 = 5a = 3, b = 5
  4. i=5: next = 3 + 5 = 8a = 5, b = 8
    输出: 8

总结

通过动态规划的迭代方法,高效计算爬楼梯的不同方法数。代码简洁且性能优化,适用于较大 n 值。### 动态规划超大白话解释

想象你要去朋友家玩,但路上有好多条岔路。你想知道从你家到朋友家总共有多少种走法。这就是动态规划要解决的问题!

大白话解释动态规划

举个具体例子 🌰:

假设你家在A点,朋友家在D点,中间有B和C两个点:

A -- B -- C -- D

每次只能走一步(比如A到B,或者B到C)

问题:从A到D有多少种走法?

  1. 分解小问题:

    • 先看A到B:只有1种走法(直接走)
    • A到C:2种走法(A→B→C 或 直接A→C?等等...这里需要重新思考)
  2. 重新思考正确分解:

    • 到B点的走法:1种(A→B)
    • 到C点的走法:2种(A→B→C 或 A→C)
    • 到D点的走法:需要从C点走过来(因为只能走一步)
  3. 关键发现:

    • 想到D点,必须先到C点
    • 所以到D的方法数 = 到C的方法数
    • 到C的方法数 = 到B的方法数 + 直接到C的方法
  4. 建立"记忆本":

    位置从A出发的方法数怎么算出来的
    B1直接走
    C2(到B的方法)+1
    D2等于到C的方法
  5. 这就是动态规划:

    • 把大问题(去D点)拆成小问题(先去B、C点)
    • 用表格记录每个点的答案
    • 后面的答案用前面的答案算出来
    • 避免重复计算(比如算D时直接查C的记录)

爬楼梯就是这样的问题:

  • 到第3级台阶 = (到第2级的方法) + (到第1级的方法)
  • 因为:从第2级走1步,或者从第1级走2步

动态规划三步骤:

  1. 拆零件:把大问题拆成小问题(比如拆解成到每一级台阶的方法)
  2. 记答案:用表格记录每个小问题的答案
  3. 拼起来:用前面小问题的答案组合出大问题的答案

为什么叫"动态"规划?

因为答案像搭积木一样:

  • 先算台阶1:1种方法
  • 再算台阶2:2种方法
  • 然后台阶3 = 台阶1 + 台阶2 = 3
  • 台阶4 = 台阶2 + 台阶3 = 5
  • 像滚雪球一样越滚越大!

生活比喻:

就像吃奥利奥饼干:

  1. 先拆开包装(拆解问题)
  2. 记住第一片饼干的味道(记录小答案)
  3. 用第一片的经验吃第二片(组合答案)
  4. 最后知道整包饼干的味道(解决大问题)

这样每次遇到新问题,都不用从头开始想,直接查之前的"记忆小本本"就行啦!🍪