力扣 LCR 099. 最小路径和 —— 动态规划入门详解
引言动态规划的核心在于将复杂问题分解为重叠子问题而「最小路径和」正是理解这一思想的经典范例。给定一个带权网格每次只能向下或向右移动求从左上到右下的最小路径和。这道题相比「粉刷房子」多了一个二维空间维度但状态转移更加直观——每个格子的值只依赖于其上方和左方的格子。本文将带你从 DP 表格构造到代码实现一步步掌握这道必刷题摘要本文详细解析力扣 LCR 099. 最小路径和的动态规划解法。给定m×n非负网格每次只能向下或向右走求左上到右下的最小路径和。定义dp[i][j]为到达(i,j)的最小路径和转移方程dp[i][j] grid[i][j] min(dp[i-1][j], dp[i][j-1])上格子/左格子二者取较小值。重点讲解初始化边界第一行只能从左边来第一列只能从上边来需先填好第一行、第一列这种边界值然后再开始动态规划。提供二维数组和 O(n) 空间优化两种代码时间复杂度 O(m×n)目录一、题目描述二、动态规划思路1. 为什么用 DP2. DP 数组的定义3. DP 数组的构造以示例 1 为例第一步初始化 dp 数组第二步从 (1,1) 开始递推双层循环4. 状态转移方程三、Java 代码实现四、代码优化空间压缩五、易错点总结特别重要⚠️ 注意点 1初始化边界不能忘⚠️ 注意点 2理清上一步来自哪里⚠️ 注意点 3空间优化时一维数组的含义六、复杂度分析总结一、题目描述给定一个包含非负整数的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二、动态规划思路1. 为什么用 DP到达(i,j)的最小路径和只依赖于到达上方(i-1,j)和左方(i,j-1)的最小路径和。因为每次只能向下或向右所以(i,j)的上一步只能是上面或左面——这就是最优子结构适合用 DP 自顶向下推导。2. DP 数组的定义dp[i][j]从左上角 (0,0) 走到 (i,j) 的最小路径和。3. DP 数组的构造以示例 1 为例输入grid [[1,3,1], [1,5,1], [4,2,1]]第一步初始化 dp 数组① 起点dp[0][0] grid[0][0] 1② 初始化第一行只能从左边来dp[0][j] dp[0][j-1] grid[0][j]即dp[0][1] dp[0][0] grid[0][1] 1 3 4dp[0][2] dp[0][1] grid[0][2] 4 1 5③ 初始化第一列只能从上边来dp[i][0] dp[i-1][0] grid[i][0]即dp[1][0] dp[0][0] grid[1][0] 1 1 2dp[2][0] dp[1][0] grid[2][0] 2 4 6初始化完成后dp 数组为下标\下标012014512待双层循环推导待双层循环推导26待双层循环推导待双层循环推导第二步从 (1,1) 开始递推双层循环对于非边界格子(i,j)其值 grid[i][j] min(dp[i-1][j], dp[i][j-1])dp[1][1] 5 min(dp[0][1]4, dp[1][0]2) 5 2 7dp[1][2] 1 min(dp[0][2]5, dp[1][1]7) 1 5 6dp[2][1] 2 min(dp[1][1]7, dp[2][0]6) 2 6 8dp[2][2] 1 min(dp[1][2]6, dp[2][1]8) 1 6 7完整 dp 数组下标\下标012014512762687最终答案dp[2][2] 74. 状态转移方程边界情况dp[0][0] grid[0][0]第一行dp[0][j] dp[0][j-1] grid[0][j]只能从左边来第一列dp[i][0] dp[i-1][0] grid[i][0]只能从上边来通用情况dp[i][j] grid[i][j] min(dp[i-1][j], dp[i][j-1])三、Java 代码实现class Solution { public int minPathSum(int[][] grid) { //1.获取矩阵的行数和列数 int row grid.length; int col grid[0].length; //2.创建dp数组 int[][] dp new int[row][col]; //3.初始化dp数组初始化边界值第一行、第一列 //初始化左上角元素 dp[0][0] grid[0][0]; //初始化第一列 for (int i 1; i row; i) { dp[i][0] dp[i - 1][0] grid[i][0]; } //初始化第一行 for (int j 1; j col; j) { dp[0][j] dp[0][j - 1] grid[0][j]; } //4.开始动态规划的核心代码填充dp数组 for(int i1;irow;i){ for(int j1;jcol;j){ //到达当前节点的最小路径 当前格子的耗费路径 min(到达左面相邻格子的最小路径 到达上面相邻格子的最小路径) dp[i][j] grid[i][j] Math.min(dp[i][j-1], dp[i-1][j]); } } //返回结果 return dp[row-1][col-1]; } }运行结果四、代码优化空间压缩因为dp[i][j]只依赖于当前行的左方和上一行的同列所以可以用一维数组滚动更新空间复杂度降至O(n)public static int minPathSum(int[][] grid) { int m grid.length; int n grid[0].length; int[] dp new int[n]; // 初始化第一行 dp[0] grid[0][0]; for (int j 1; j n; j) { dp[j] dp[j-1] grid[0][j]; } // 从第二行开始 for (int i 1; i m; i) { dp[0] grid[i][0]; // 第一列只能从上边来 for (int j 1; j n; j) { dp[j] grid[i][j] Math.min(dp[j], dp[j-1]); // dp[j]旧值代表上方dp[j-1]新值代表左方 } } return dp[n-1]; }五、易错点总结特别重要⚠️ 注意点 1初始化边界不能忘很多同学直接写双层循环导致i0或j0时dp[i-1][j]或dp[i][j-1]越界。正确做法先单独初始化第一行和第一列再从(1,1)开始循环。⚠️ 注意点 2理清上一步来自哪里因为只能向下或向右走所以到达(i,j)的上一步只能是上方(i-1,j)或左方(i,j-1)不是四个方向也不是斜对角。⚠️ 注意点 3空间优化时一维数组的含义滚动数组版本中dp[j]在更新前代表上一行(i-1,j)的值dp[j-1]已经更新为当前行(i,j-1)的值所以Math.min(dp[j], dp[j-1])正好对应min(dp[i-1][j], dp[i][j-1])不要搞反顺序。六、复杂度分析版本时间复杂度空间复杂度二维数组O(m × n)O(m × n)一维滚动数组O(m × n)O(n)总结这道题是动态规划中路径类问题的入门经典核心思想是定义dp[i][j]为到达(i,j)的最小路径和先初始化边界由于第一行的每个格子只可能从左方格子而来第一列的每个格子只可能从上方的格子而来。所以此时初始化边界就是先初始化第一行、第一列的每个格子的值。通用转移dp[i][j] grid[i][j] min(dp[i-1][j], dp[i][j-1])最终答案在dp[m-1][n-1]相比「粉刷房子」本题的 DP 表格多了一个空间维度但转移关系更加直观——上一步来自哪里一目了然。掌握这道题后可以继续挑战「不同路径」「三角形最小路径和」等同类问题。希望这篇文章能帮助你更好地理解动态规划如果有问题欢迎留言讨论

相关新闻

终极指南:如何在Windows任务栏实现桌面监控和性能优化

终极指南:如何在Windows任务栏实现桌面监控和性能优化

终极指南:如何在Windows任务栏实现桌面监控和性能优化 【免费下载链接】TrafficMonitorPlugins 用于TrafficMonitor的插件 项目地址: https://gitcode.com/gh_mirrors/tr/TrafficMonitorPlugins 还在为复杂的系统监控工具烦恼吗?每次想查看CPU温度…

2026/7/21 16:32:17 阅读更多 →
Stable-Baselines3 最佳实践:避免常见陷阱的 7 个实用技巧

Stable-Baselines3 最佳实践:避免常见陷阱的 7 个实用技巧

Stable-Baselines3 最佳实践:避免常见陷阱的 7 个实用技巧 【免费下载链接】rl-tutorial-jnrr19 Stable-Baselines tutorial for Journes Nationales de la Recherche en Robotique 2019 项目地址: https://gitcode.com/gh_mirrors/rl/rl-tutorial-jnrr19 S…

2026/7/21 16:31:17 阅读更多 →
OAuth-Plugin生成器详解:快速创建OAuth提供者和消费者

OAuth-Plugin生成器详解:快速创建OAuth提供者和消费者

OAuth-Plugin生成器详解:快速创建OAuth提供者和消费者 【免费下载链接】oauth-plugin Rails plugin for OAuth 项目地址: https://gitcode.com/gh_mirrors/oa/oauth-plugin OAuth-Plugin是一款专为Rails应用设计的插件,提供了强大的生成器功能&am…

2026/7/21 16:31:17 阅读更多 →

最新新闻

CoreFileKit 文件操作常见故障:句柄泄漏、URI路径转换错误排查手册

CoreFileKit 文件操作常见故障:句柄泄漏、URI路径转换错误排查手册

适配鸿蒙7 API25 kit.CoreFileKit,面向工业/政务/零售Kiosk终端沙箱文件、图纸/证照/工单文档场景,覆盖句柄泄漏、URI转换失败、沙箱权限越界、大文件OOM、文件丢失、多进程锁冲突、安全标签失效七大高频故障,每条含现象、根因、错误代码、标…

2026/7/21 21:32:52 阅读更多 →
Web自动化测试平台架构设计与落地实践:从零搭建企业级测试中台

Web自动化测试平台架构设计与落地实践:从零搭建企业级测试中台

1. 项目概述与核心价值最近几年,但凡聊到软件测试,尤其是Web应用测试,“自动化”这个词的热度就没下来过。从最初几个测试工程师自己写脚本,到后来引入Selenium、Cypress这些框架,再到今天大家开始琢磨怎么把零散的脚本…

2026/7/21 21:32:52 阅读更多 →
协同过滤推荐系统工程化实践:从算法到SpringBoot服务

协同过滤推荐系统工程化实践:从算法到SpringBoot服务

最近在整理一个老项目时,翻出了一个基于协同过滤的商品推荐系统。当时为了快速验证算法效果,直接上手就写,结果在数据量稍微大一点后,系统就慢得让人怀疑人生。这让我意识到,很多关于“协同过滤”的教程,可…

2026/7/21 21:32:52 阅读更多 →
Google Gemma-4-26B-A4B-it-GGUF:如何在个人电脑上运行260亿参数大语言模型

Google Gemma-4-26B-A4B-it-GGUF:如何在个人电脑上运行260亿参数大语言模型

Google Gemma-4-26B-A4B-it-GGUF:如何在个人电脑上运行260亿参数大语言模型 【免费下载链接】google_gemma-4-26B-A4B-it-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/bartowski/google_gemma-4-26B-A4B-it-GGUF Google Gemma-4-26B-A4B-it-GGUF是一…

2026/7/21 21:32:52 阅读更多 →
Freyr-js容器化部署方案:多平台音乐下载服务的高效构建与优化

Freyr-js容器化部署方案:多平台音乐下载服务的高效构建与优化

Freyr-js容器化部署方案:多平台音乐下载服务的高效构建与优化 【免费下载链接】freyr-js A tool for downloading songs from music streaming services like Spotify and Apple Music. 项目地址: https://gitcode.com/gh_mirrors/fr/freyr-js 在数字化音乐时…

2026/7/21 21:32:51 阅读更多 →
GameHackingCode状态机设计:构建智能游戏机器人的关键步骤

GameHackingCode状态机设计:构建智能游戏机器人的关键步骤

GameHackingCode状态机设计:构建智能游戏机器人的关键步骤 【免费下载链接】GameHackingCode Example code for the book http://www.nostarch.com/gamehacking . PLEASE READ THE README 项目地址: https://gitcode.com/gh_mirrors/ga/GameHackingCode Game…

2026/7/21 21:31:51 阅读更多 →

日新闻

Octane Render与C4D汉化版安装与优化指南

Octane Render与C4D汉化版安装与优化指南

1. Octane Render与C4D的黄金组合:为什么选择这个方案?在三维创作领域,渲染器的选择往往决定了作品的最终呈现质量和工作效率。作为Cinema 4D(C4D)用户,Octane Render的GPU加速特性与实时预览功能&#xff…

2026/7/21 0:00:19 阅读更多 →
GPMC接口设计:异步/同步模式与多路复用配置实战

GPMC接口设计:异步/同步模式与多路复用配置实战

1. GPMC接口设计:从硬件连接到软件配置的全局视角在嵌入式系统开发中,尤其是基于TI Sitara系列如AM263x这类高性能微控制器的项目里,外部存储器的扩展几乎是绕不开的一环。无论是存放大量非易失性代码的NOR Flash,还是作为高速数据…

2026/7/21 0:00:19 阅读更多 →
UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

1. 项目概述:UE5 GAS RPG被动技能的核心价值在UE5里用GAS(Gameplay Ability System)做RPG游戏,主动技能像是你手里的武器,按一下打一下,逻辑直接,反馈也快。但被动技能,它更像是你身…

2026/7/21 0:00:19 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻