news 2026/11/3 15:34:37

LeetCode 746题解析:动态规划解决最小花费爬楼梯问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 746题解析:动态规划解决最小花费爬楼梯问题

1. 问题背景与核心理解

这道LeetCode 746题"使用最小花费爬楼梯"是一个经典的动态规划入门题目。题目描述为:给定一个整数数组cost,其中cost[i]是从楼梯第i个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或两个台阶。你可以选择从下标为0或1的台阶开始爬楼梯,请计算并返回达到楼梯顶部的最小花费。

在实际开发面试中,这类动态规划问题出现的频率极高。我刚开始刷题时也在这类问题上栽过跟头,后来通过系统化的训练才掌握了其中的套路。这道题看似简单,但蕴含着动态规划的经典思考模式,特别适合用来理解最优子结构和状态转移的概念。

2. 动态规划解法详解

2.1 状态定义与转移方程

首先我们需要明确dp数组的含义。在这道题中,dp[i]表示到达第i级台阶所需的最小花费。注意这个定义非常关键,很多初学者容易在这里混淆"到达"和"站在"的区别。

根据题意,每次可以跨1或2个台阶,因此到达第i级台阶有两种方式:

  1. 从i-1级跨1步上来,花费为dp[i-1] + cost[i-1]
  2. 从i-2级跨2步上来,花费为dp[i-2] + cost[i-2]

因此状态转移方程为: dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])

2.2 初始化与边界条件

初始化是动态规划最容易出错的部分。根据题意:

  • dp[0] = 0 (可以从第0级开始,初始花费为0)
  • dp[1] = 0 (也可以从第1级开始,初始花费为0)

这里有个易错点:虽然cost数组的下标从0开始,但dp数组需要考虑到达第0级和第1级的情况。

2.3 完整代码实现

def minCostClimbingStairs(cost): n = len(cost) dp = [0] * (n + 1) for i in range(2, n + 1): dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]) return dp[n]

这个实现的时间复杂度是O(n),空间复杂度也是O(n)。在面试中,面试官可能会追问如何优化空间复杂度。

3. 空间优化技巧

3.1 滚动数组优化

观察状态转移方程可以发现,dp[i]只依赖于dp[i-1]和dp[i-2],因此我们可以只用两个变量来存储中间结果,而不需要维护整个dp数组。

优化后的实现:

def minCostClimbingStairs(cost): n = len(cost) prev, curr = 0, 0 for i in range(2, n + 1): next_val = min(curr + cost[i-1], prev + cost[i-2]) prev, curr = curr, next_val return curr

这样空间复杂度就优化到了O(1),这在处理大规模数据时非常有用。

4. 常见错误与调试技巧

4.1 初始化错误

最常见的错误是初始化不正确。比如有人会把dp[1]初始化为cost[0],这是没有理解题目允许从第1级开始,初始花费应该是0。

调试技巧:在纸上画出前3个台阶的dp值,手动计算验证初始化是否正确。

4.2 数组越界

另一个常见错误是忘记dp数组的长度应该是n+1而不是n。因为要到达的是第n级台阶(顶楼)。

调试技巧:对于边界情况(如cost为空或只有1个元素)要特别测试。

4.3 状态定义混淆

有些人会把dp[i]定义为"站在第i级台阶的总花费",这样会导致状态转移方程复杂化,容易出错。

经验法则:在爬楼梯问题中,dp[i]通常定义为"到达"而非"站在"的花费。

5. 问题变种与扩展

5.1 最多k步的爬楼梯

如果题目改为每次可以爬1到k步,该如何修改解法?这时状态转移方程变为: dp[i] = min(dp[i-j] + cost[i-j] for j in range(1, k+1) if i-j >=0)

5.2 不能连续跳相同步数

如果增加限制条件"不能连续两次跳相同的步数",就需要在状态中额外记录上一步的跳跃距离。

5.3 实际工程应用

这类问题在实际中有很多应用场景,比如:

  • 网络路由选择最小延迟路径
  • 游戏中的最优路径规划
  • 金融中的最优投资策略

6. 刷题建议与心得

通过这道题,我总结了几个动态规划的学习要点:

  1. 明确状态定义是关键,不同的定义会导致完全不同的解法
  2. 先写出暴力递归,再优化为记忆化搜索,最后转为递推
  3. 画状态转移图有助于理解问题
  4. 边界条件要单独测试
  5. 空间优化通常是最后考虑的事情

在实际面试中,建议按照以下步骤解答:

  1. 先说明暴力解法的时间复杂度
  2. 指出重复计算的问题
  3. 提出用动态规划优化
  4. 明确状态定义和转移方程
  5. 讨论初始化和边界条件
  6. 最后考虑空间优化

这道题虽然标为简单,但包含了动态规划的核心思想。我建议初学者至少做3遍:

  • 第一遍理解题意和基本解法
  • 第二遍尝试自己写出代码
  • 第三遍思考优化和变种
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/3 15:33:08

SkyWalking分布式追踪与性能监控实战指南

1. SkyWalking核心能力解析Apache SkyWalking作为云原生时代分布式系统的"CT扫描仪",其核心价值在于为复杂的微服务架构提供全栈式观测能力。我在实际生产环境中使用SkyWalking已有三年时间,它成功帮助我们团队将平均故障定位时间从4小时缩短到…

作者头像 李华
网站建设 2026/11/3 15:32:36

VS Code插件自动化合并代码,高效完成软著申请

1. 项目背景与需求解析作为一名长期从事物联网平台开发的工程师,我最近在为ThingsBoard项目申请软件著作权时遇到了一个看似简单却颇为棘手的问题:如何将分散在不同目录中的源代码文件合并成一个符合软著申请要求的文档。根据《计算机软件著作权登记指南…

作者头像 李华
网站建设 2026/11/3 15:32:27

MQL4锁仓对冲EA源码拆解:订单识别、自动止盈与实盘避坑

简介:锁仓顺势加码EA源码是一份面向外汇自动交易学习者与MQL4开发者的实战代码资料,围绕MetaTrader平台上锁仓与顺势加码策略展开,适合具备一定EA基础、想弄懂对冲单管理与自动止盈逻辑的读者。压缩包仅含1个doc文件,约45KB&#…

作者头像 李华
网站建设 2026/11/3 15:32:15

K8s集群内存泄漏故障排查与云平台优化实践

1. 事故现场还原:虚拟服务器集群的集体宕机事件 那天凌晨3点17分,监控大屏突然跳出9个刺眼的红色警报框。作为运维负责人,我盯着不断刷新的告警信息,发现整个K8s集群的worker节点全部失去响应。更诡异的是,这些服务器明…

作者头像 李华
网站建设 2026/11/3 15:32:09

设计模式选择方法论:五问法与实战指南

1. 设计模式选择方法论:从理论到实战的完整指南 作为从业十余年的架构师,我见过太多团队在设计模式应用上陷入困境——不是不理解模式本身,而是在具体场景中难以快速选择最合适的方案。本文将分享一套经过实战检验的设计模式选择方法论&#…

作者头像 李华
网站建设 2026/11/3 15:29:39

共享储能模式下微网运营商与用户聚合商的博弈与优化

1. 项目背景与行业痛点 在新型电力系统建设背景下,共享储能作为能源互联网的重要基础设施,正在重塑传统电力市场的利益格局。这个项目探讨的是微网运营商与用户聚合商在共享储能模式下的复杂博弈关系——就像两个精明的商人共用同一个仓库,既…

作者头像 李华