2026/4/18 12:00:01
网站建设
项目流程
模板网站免费下载,十大互联网广告公司,企业网站建设三个原则,基于WordPress开发Java版LeetCode热题100之最小路径和#xff1a;从入门到精通的全面解析 摘要#xff1a;本文深入剖析 LeetCode 热题 100 中的经典动态规划题目——「最小路径和」。我们将从原题回顾出发#xff0c;逐步展开分析、解法设计、代码实现、复杂度评估#xff0c;并延伸至算法优…Java版LeetCode热题100之最小路径和从入门到精通的全面解析摘要本文深入剖析 LeetCode 热题 100 中的经典动态规划题目——「最小路径和」。我们将从原题回顾出发逐步展开分析、解法设计、代码实现、复杂度评估并延伸至算法优化、面试应对、实际应用场景等多个维度。全文结构清晰、内容翔实适合准备算法面试或希望夯实动态规划基础的读者。一、原题回顾题目描述给定一个包含非负整数的m x n网格grid请找出一条从左上角到右下角的路径使得路径上的数字总和为最小。说明每次只能向下或者向右移动一步。示例 1输入grid [[1,3,1],[1,5,1],[4,2,1]] 输出7 解释因为路径 1→3→1→1→1 的总和最小。示例 2输入grid [[1,2,3],[4,5,6]] 输出12约束条件m grid.lengthn grid[i].length1 m, n 2000 grid[i][j] 200这道题是典型的网格路径问题要求在有限移动方向仅能向右或向下的前提下找到一条路径使得路径上的数字总和最小。它不仅考察了我们对动态规划的理解也涉及状态转移、边界处理等关键编程技巧。二、原题分析2.1 问题本质本题的核心在于在有向无环图DAG中寻找从起点到终点的最短路径权重为格子中的数值。由于每次只能向右或向下走整个网格实际上构成了一个 DAG不存在回路因此非常适合使用动态规划求解。2.2 关键限制移动方向受限只能向右或向下 → 每个位置(i, j)只能由(i-1, j)或(i, j-1)到达。非负权重所有grid[i][j] ≥ 0→ 无需考虑负权边导致的复杂情况如 Bellman-Ford贪心或 DP 均可适用。唯一目标从(0,0)到(m-1, n-1)的最小路径和。2.3 直观思考如果我们尝试暴力枚举所有路径共有 C(mn-2, m-1) 条时间复杂度将呈指数级增长显然不可行。因此需要一种更高效的方法——动态规划。三、答案构思动态规划设计3.1 状态定义设dp[i][j]表示从左上角(0, 0)走到位置(i, j)所需的最小路径和。我们的目标是求出dp[m-1][n-1]。3.2 状态转移方程由于只能从上方或左方到达(i, j)因此若i 0且j 0d p [ i ] [ j ] min ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) g r i d [ i ] [ j ] dp[i][j] \min(dp[i-1][j], dp[i][j-1]) grid[i][j]dp[i][j]min(dp[i−1][j],dp[i][j−1])grid[i][j]若在第一行i 0, j 0d p [ 0 ] [ j ] d p [ 0 ] [ j − 1 ] g r i d [ 0 ] [ j ] dp[0][j] dp[0][j-1] grid[0][j]dp[0][j]dp[0][j−1]grid[0][j]若在第一列j 0, i 0d p [ i ] [ 0 ] d p [ i − 1 ] [ 0 ] g r i d [ i ] [ 0 ] dp[i][0] dp[i-1][0] grid[i][0]dp[i][0]dp[i−1][0]grid[i][0]起点d p [ 0 ] [ 0 ] g r i d [ 0 ] [ 0 ] dp[0][0] grid[0][0]dp[0][0]grid[0][0]3.3 边界处理网格为空返回 0。单行或单列路径唯一直接累加即可。3.4 计算顺序由于dp[i][j]依赖于上方和左方的状态我们可以按行优先或列优先顺序遍历网格确保在计算dp[i][j]时dp[i-1][j]和dp[i][j-1]已经被计算。四、完整答案Java 实现classSolution{publicintminPathSum(int[][]grid){// 边界检查if(gridnull||grid.length0||grid[0].length0){return0;}introwsgrid.length;intcolsgrid[0].length;// 创建 dp 表int[][]dpnewint[rows][cols];// 初始化起点dp[0][0]grid[0][0];// 初始化第一列for(inti1;irows;i){dp[i][0]dp[i-1][0]grid[i][0];}// 初始化第一行for(intj1;jcols;j){dp[0][j]dp[0][j-1]grid[0][j];}// 填充其余位置for(inti1;irows;i){for(intj1;jcols;j){dp[i][j]Math.min(dp[i-1][j],dp[i][j-1])grid[i][j];}}returndp[rows-1][cols-1];}}五、代码分析5.1 结构清晰边界处理防止空指针异常。初始化单独处理第一行和第一列避免在主循环中频繁判断边界。主逻辑双重循环填充dp表逻辑简洁。5.2 正确性验证以示例1为例输入grid [[1,3,1],[1,5,1],[4,2,1]]构建dp表过程如下012014512762687最终dp[2][2] 7与预期一致。5.3 鲁棒性支持1x1网格直接返回grid[0][0]。支持单行如[[1,2,3]]或单列如[[1],[2],[3]]。六、时间复杂度与空间复杂度分析6.1 时间复杂度需要遍历整个m x n网格一次。每个单元格的计算为 O(1)。总时间复杂度O(mn)6.2 空间复杂度使用了一个m x n的dp数组。原始空间复杂度O(mn)⚠️ 注意题目未要求保留原始grid因此可以原地修改grid作为dp表将空间复杂度降至 O(1)。但通常为了代码清晰性和避免副作用建议使用额外空间。七、问题解答FAQQ1为什么不能用贪心算法答贪心策略如每一步选较小的邻居可能陷入局部最优。例如grid [[1, 3], [1, 5]]贪心会选择1 → 1 → 5 7但最优是1 → 3 → 5 9不对等等这里其实贪心是对的再看反例grid [[1, 2, 3], [4, 8, 2], [1, 5, 3]]贪心第一步选1→2比1→4小但后续可能被迫走大数。而最优路径可能是1→4→1→5→3 14而贪心路径1→2→3→2→3 11似乎还是对的实际上在只能向右/向下且权重非负的情况下贪心并不总是失败但无法保证全局最优。动态规划通过记录所有子问题的最优解确保最终结果正确。Q2能否从右下角反向推导答可以。定义dp[i][j]为从(i,j)到(m-1,n-1)的最小路径和则d p [ i ] [ j ] g r i d [ i ] [ j ] min ( d p [ i 1 ] [ j ] , d p [ i ] [ j 1 ] ) dp[i][j] grid[i][j] \min(dp[i1][j], dp[i][j1])dp[i][j]grid[i][j]min(dp[i1][j],dp[i][j1])需从右下角开始反向填充。逻辑等价但正向更直观。Q3如果允许向上或向左移动怎么办答此时图中可能出现环问题变为带权最短路径问题需使用 Dijkstra 算法因权重非负或 Floyd-Warshall小规模。八、优化思路8.1 空间优化滚动数组观察发现计算第i行时只依赖第i-1行和当前行已计算的部分。因此可用一维数组代替二维dp。优化后代码publicintminPathSum(int[][]grid){if(gridnull||grid.length0||grid[0].length0)return0;introwsgrid.length,colsgrid[0].length;int[]dpnewint[cols];dp[0]grid[0][0];// 初始化第一行for(intj1;jcols;j){dp[j]dp[j-1]grid[0][j];}// 从第二行开始for(inti1;irows;i){dp[0]grid[i][0];// 第一列只能从上方来for(intj1;jcols;j){dp[j]Math.min(dp[j],dp[j-1])grid[i][j];}}returndp[cols-1];}空间复杂度O(n)注若m n可按列滚动进一步优化为 O(min(m, n))。8.2 原地修改不推荐但可行直接复用grid数组for(inti0;irows;i){for(intj0;jcols;j){if(i0j0)continue;elseif(i0)grid[i][j]grid[i][j-1];elseif(j0)grid[i][j]grid[i-1][j];elsegrid[i][j]Math.min(grid[i-1][j],grid[i][j-1]);}}returngrid[rows-1][cols-1];优点O(1) 空间缺点破坏输入数据不符合函数式编程原则。九、数据结构与算法基础知识点回顾9.1 动态规划Dynamic Programming, DP核心思想将复杂问题分解为重叠子问题通过存储子问题解避免重复计算。适用条件最优子结构全局最优解包含子问题最优解。重叠子问题子问题被多次调用。实现方式自顶向下记忆化搜索或自底向上填表法。9.2 网格 DP 的通用模式状态dp[i][j]表示到达(i,j)的某种最优值。转移根据移动规则如右/下决定依赖关系。边界处理第一行、第一列或边缘情况。9.3 空间优化技巧滚动数组当状态仅依赖前一行/列时用一维数组替代二维。状态压缩利用位运算或数学变换减少状态表示。十、面试官提问环节模拟Q1你能解释一下为什么这个 DP 是正确的吗答因为每一步的决策只依赖于已知的最优子路径上方或左方且我们从小到大构建解确保每个dp[i][j]都是最优的。这满足最优子结构性质。Q2如果网格中有障碍物如 -1 表示不可通行如何修改答遇到障碍物时dp[i][j] INF表示不可达。初始化时若起点是障碍直接返回 0 或 -1。转移时跳过障碍位置。Q3如何输出具体的最小路径而不仅是和答在 DP 过程中记录“选择来源”来自上 or 左最后从终点回溯即可。需额外parent[i][j]数组。Q4时间和空间复杂度还能再优化吗答时间已是最优 O(mn)因必须读取每个格子。空间可优化至 O(n) 或 O(min(m,n))如前所述。十一、这道算法题在实际开发中的应用虽然“最小路径和”看似抽象但它在多个领域有实际价值11.1 图像处理图像 seam carving接缝裁剪寻找能量最低的像素路径进行图像缩放其核心就是类似 DP 的路径搜索。11.2 路径规划机器人在网格地图中寻找能耗最低的路径每个格子代表不同地形阻力。11.3 金融风控在多阶段决策中如贷款审批流程每个节点有成本寻找总成本最低的审批路径。11.4 编译器优化指令调度中寻找执行代价最小的指令序列。启示DP 不仅是面试题更是解决多阶段决策优化问题的强大工具。十二、相关题目推荐掌握本题后可挑战以下变种或进阶题题目链接难度关键变化62. 不同路径LeetCode中等求路径数量无权重63. 不同路径 IILeetCode中等加入障碍物120. 三角形最小路径和LeetCode中等三角形结构自底向上 DP174. 地下城游戏LeetCode困难需反向 DP考虑生命值约束931. 下降路径最小和LeetCode中等可向左下、正下、右下移动建议按顺序练习逐步提升 DP 建模能力。十三、总结与延伸13.1 核心收获动态规划建模能力学会定义状态、写出转移方程、处理边界。空间优化意识理解滚动数组的原理与应用场景。问题抽象能力将现实问题转化为网格路径模型。13.2 延伸思考如果允许对角线移动→ 转移方程增加dp[i-1][j-1]。如果要求路径必须经过某个点→ 分段 DP起点→中点→终点。如果网格非常大如 1e5 x 1e5→ 需考虑稀疏表示或启发式搜索如 A*。13.3 学习建议动手实现不要只看代码自己写一遍并调试。画图辅助用表格模拟 DP 过程加深理解。举一反三做完后思考“如果条件变了怎么改”结语算法之美在于将复杂问题化繁为简。最小路径和虽是一道中等题却蕴含了动态规划的精髓。希望本文能助你在算法之路上走得更远、更稳。欢迎点赞、收藏、评论交流关注我获取更多 LeetCode 热题深度解析字数统计约 9200 字含代码与公式适用读者LeetCode 刷题者、校招/社招面试准备者、算法爱好者