LeetCode-064网格DP如何求最小路径和?

摘要:本题在线练习:LeetCode 64. 最小路径和 - 在线练习(免费 · 无需登录 · AI 辅助)(https:onefly.topzero2Leetcodeplaygroun
本题在线练习:LeetCode 64. 最小路径和 - 在线练习(免费 · 无需登录 · AI 辅助)(https://onefly.top/zero2Leetcode/playground.html?id=64) 配套刷题网站 Zero2Leetcode —— 内置本地 OJ + AI 教练,零门槛开始刷 Hot 100。 题目概述 给定一个 m x n 的非负整数网格 grid,从左上角走到右下角,每次只能向右或向下。求路径上数字之和的 最小值(通常包含起点和终点)。 这题和“不同路径”非常像,只是把“计数”换成了“取最小和”。 核心思路:到达 (i, j) 的最小代价 设 dp[i][j] 表示到达 (i, j) 的最小路径和。 最后一步同样只有两种来源: 从上方 (i-1, j) 走下来 从左方 (i, j-1) 走过来 所以转移: dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] 边界: dp[0][0] = grid[0][0] 第一行只能从左边来(累加) 第一列只能从上边来(累加) 先从最自然的二维 DP 讲起 代码实现(二维 dp) class Solution: def minPathSum(self, grid: list[list[int]]) -> int: m, n = len(grid), len(grid[0]) dp = [[0] * n for _ in range(m)] dp[0][0] = grid[0][0] for j in range(1, n): dp[0][j] = dp[0][j - 1] + grid[0][j] for i in range(1, m): dp[i][0] = dp[i - 1][0] + grid[i][0] for i in range(1, m): for j in range(1, n): dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j] return dp[m - 1][n - 1] 逐行拆解:边界为什么要“累加” 第一行 (0, j) 只能从 (0, j-1) 来,因此最小和就是一路加过来。 第一列 (i, 0) 同理,只能从 (i-1, 0) 来。 从 (1,1) 起,每个格子才真正存在“从上或从左二选一”的分叉。 手动模拟:用例 grid = [[1,3,1],[1,5,1],[4,2,1]] 初始化: dp[0][0] = 1 第一行:1, 4, 5 第一列:1, 2, 6 继续填: dp[1][1] = min(4, 2) + 5 = 7 dp[1][2] = min(5, 7) + 1 = 6 dp[2][1] = min(7, 6) + 2 = 8 dp[2][2] = min(6, 8) + 1 = 7 答案 7,对应路径 1 -> 3 -> 1 -> 1 -> 1。 进阶:一维 DP 空间优化 同样的观察:dp[i][j] 只依赖上方和左方。
阅读全文