【LeetCode】70. 爬楼梯
解题思路
爬楼梯问题是一个经典的动态规划问题,其本质是斐波那契数列的变种。通过分析可以发现,到达第 n 阶楼梯的方法数等于到达第 n-1 阶和第 n-2 阶方法数之和,因为最后一步可以是 爬1阶 或 爬2阶。因此可以用 动态规划 或 斐波那契数列 的优化方法解决。
关键步骤
- 状态定义:设
dp[i]表示爬到第i阶的方法数。 - 状态转移方程:
dp[i] = dp[i-1] + dp[i-2]。 - 边界条件:
dp[0] = 1(地面,视为一种方法)dp[1] = 1(1阶楼梯只有1种方法)dp[2] = 2(2阶楼梯有2种方法)
- 空间优化:由于每次只需要前两个状态,可以用两个变量代替数组,将空间复杂度优化到
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 }
代码注释
- 边界处理:当
n=1时直接返回1。 - 变量初始化:
prev表示dp[i-2],current表示dp[i-1],初始化为1和2(对应n=1和n=2的情况)。 - 循环计算:从第
3阶开始迭代,通过prev和current的滚动更新,计算当前阶的方法数。 - 时间复杂度:
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) = 1F(2) = 2F(n) = F(n-1) + F(n-2)(n ≥ 3)
例如:
n=3对应F(4)=3n=4对应F(5)=5
进一步思考
若问题扩展为“每次可爬 1~m 个台阶”,则需用 完全背包问题 的思路解决,状态转移方程为: dp[i] = dp[i-1] + dp[i-2] + ... + dp[i-m]

浙公网安备 33010602011771号