【LeetCode】70. 爬楼梯

leetcode

 

解题思路

爬楼梯问题是一个经典的动态规划问题,其本质是斐波那契数列的变种。通过分析可以发现,到达第 n 阶楼梯的方法数等于到达第 n-1 阶和第 n-2 阶方法数之和,因为最后一步可以是 ​​爬1阶​​ 或 ​​爬2阶​​。因此可以用 ​​动态规划​​ 或 ​​斐波那契数列​​ 的优化方法解决。

关键步骤

  1. ​​状态定义​​:设 dp[i] 表示爬到第 i 阶的方法数。
  2. ​​状态转移方程​​:dp[i] = dp[i-1] + dp[i-2]
  3. ​​边界条件​​:
    • dp[0] = 1(地面,视为一种方法)
    • dp[1] = 1(1阶楼梯只有1种方法)
    • dp[2] = 2(2阶楼梯有2种方法)
  4. ​​空间优化​​:由于每次只需要前两个状态,可以用两个变量代替数组,将空间复杂度优化到 O(1)。

实现代码

func climbStairs(n int) int {
    if n == 1 {
        return 1
    }
    // 初始化前两个状态:1阶和2阶的方法数
    prev, current := 1, 2
    for i := 3; i <= n; i++ {
        // 计算当前状态,并更新前两个状态
        prev, current = current, prev + current
    }
    return current
}

代码注释

  1. ​​边界处理​​:当 n=1 时直接返回 1
  2. ​​变量初始化​​:prev 表示 dp[i-2]current 表示 dp[i-1],初始化为 1 和 2(对应 n=1 和 n=2 的情况)。
  3. ​​循环计算​​:从第 3 阶开始迭代,通过 prev 和 current 的滚动更新,计算当前阶的方法数。
  4. ​​时间复杂度​​:O(n),空间复杂度:O(1)。

示例测试

func main() {
    fmt.Println(climbStairs(2)) // 输出 2
    fmt.Println(climbStairs(3)) // 输出 3
    fmt.Println(climbStairs(4)) // 输出 5(1+1+1+1, 1+1+2, 1+2+1, 2+1+1, 2+2)
}

复杂度分析

  • ​​时间复杂度​​:O(n),需遍历 n 次计算每一步的状态。
  • ​​空间复杂度​​:O(1),仅用两个变量存储中间结果。

数学解释

问题等价于斐波那契数列的第 n+1 项:

  • F(1) = 1
  • F(2) = 2
  • F(n) = F(n-1) + F(n-2)n ≥ 3

例如:

  • n=3 对应 F(4)=3
  • n=4 对应 F(5)=5

进一步思考

若问题扩展为“每次可爬 1~m 个台阶”,则需用 ​​完全背包问题​​ 的思路解决,状态转移方程为:
  dp[i] = dp[i-1] + dp[i-2] + ... + dp[i-m]

posted @ 2025-04-24 10:41  云隙之间  阅读(24)  评论(0)    收藏  举报