有限制的楼梯攀登问题 | 青训营X豆包MarsCode 技术训练营

45 阅读2分钟

有限制的楼梯攀登问题解析

问题描述
小U面临一个特殊的楼梯攀登挑战:

  1. 每次可以选择走1步或2步
  2. 不能连续走2步
  3. 需要计算从底部到顶端的所有可能走法
  4. 给定楼梯层数n,计算总共有多少种不同的走法

解题思路

  1. 动态规划分析
  • 定义状态:dp[i][j] 表示爬到第i层,上一步走了j步的方案数
  • 状态转移:根据上一步的步数决定当前可以走的步数
  • 最终结果:dp[n][1] + dp[n][2]
  1. 状态转移规则
  • 如果上一步走了1步,当前可以走1步或2步

  • 如果上一步走了2步,当前只能走1步

  • 状态转移方程:

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

代码实现

def climb_stairs(n: int) -> int:
    # 处理特殊情况
    if n <= 1:
        return 1
    if n == 2:
        return 2
        
    # 创建动态规划数组
    dp = [[0] * 3 for _ in range(n + 1)]
    
    # 初始化基础状态
    dp[1][1] = 1  # 第1层走1步
    dp[2][1] = 1  # 第2层走两个1步
    dp[2][2] = 1  # 第2层走一个2步
    
    # 状态转移
    for i in range(3, n + 1):
        dp[i][1] = dp[i-1][1] + dp[i-1][2]  # 当前走1步
        dp[i][2] = dp[i-2][1]  # 当前走2步
    
    return dp[n][1] + dp[n][2]

代码解析

  1. 特殊情况处理
  • n≤1时直接返回1
  • n=2时直接返回2
  1. 动态规划数组
  • 使用二维数组dp[i][j]存储状态
  • i代表当前层数
  • j代表最后一步的步数(1或2)
  1. 状态转移过程
  • 遍历每一层计算可能的方案数
  • 分别处理走1步和走2步的情况

优化版本

def climb_stairs_optimized(n: int) -> int:
    if n <= 1:
        return 1
    if n == 2:
        return 2
        
    # 只记录前两层状态
    one_step = [1, 1]  # [走1步, 走2步]
    two_steps = [1, 0]  # [走1步, 走2步]
    
    for i in range(3, n + 1):
        current = [0, 0]
        current[0] = one_step[0] + one_step[1]  # 走1步
        current[1] = two_steps[0]  # 走2步
        two_steps = one_step
        one_step = current
        
    return one_step[0] + one_step[1]

时间复杂度分析

  1. 时间复杂度
  • 基础版本:O(n),需要遍历n个状态
  • 优化版本:O(n),循环次数不变
  1. 空间复杂度
  • 基础版本:O(n),需要二维数组存储所有状态
  • 优化版本:O(1),只需要常数空间存储状态