LeetCode 热题 100 | 64. 最小路径和
大家好,今天我们来解决一道经典的动态规划问题——最小路径和。这道题在 LeetCode 上被标记为中等难度,要求找到从网格的左上角到右下角的路径,使得路径上的数字总和为最小。
问题描述
给定一个包含非负整数的 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
解题思路
核心思想
-  
动态规划:
- 使用动态规划(DP)来解决这个问题。
 - 定义 
dp[i][j]为从网格的左上角到达位置(i, j)的最小路径和。 - 状态转移方程为:
[
dp[i][j] = \min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
]
其中,dp[i-1][j]表示从上方到达(i, j)的最小路径和,dp[i][j-1]表示从左方到达(i, j)的最小路径和。 
 -  
初始化:
dp[0][0] = grid[0][0],因为从起点到起点的路径和就是起点的值。- 第一行和第一列的所有位置只能从一个方向到达,因此初始化为累加值。
 
 -  
遍历:
- 遍历整个网格,根据状态转移方程更新 
dp[i][j]。 
 - 遍历整个网格,根据状态转移方程更新 
 
Python代码实现
class Solution:def minPathSum(self, grid):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]
 
代码解析
-  
初始化:
dp数组初始化为一个m x n的二维列表,所有值初始化为 0。dp[0][0] = grid[0][0],因为从起点到起点的路径和就是起点的值。- 第一行和第一列的所有位置只能从一个方向到达,因此初始化为累加值。
 
 -  
状态转移:
- 遍历从 
(1, 1)到(m-1, n-1)的每个位置(i, j)。 - 对于每个位置 
(i, j),更新dp[i][j]为min(dp[i-1][j], dp[i][j-1]) + grid[i][j]。 
 - 遍历从 
 -  
返回结果:
- 最终结果存储在 
dp[m-1][n-1]中,表示从左上角到右下角的最小路径和。 
 - 最终结果存储在 
 
复杂度分析
- 时间复杂度:O(m * n),其中 
m和n分别是网格的行数和列数。需要遍历整个网格。 - 空间复杂度:O(m * n),使用了大小为 
m x n的dp数组。 
示例运行
示例 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
 
总结
通过动态规划的方法,我们可以高效地解决最小路径和问题。状态转移方程 dp[i][j] = \min(dp[i-1][j], dp[i][j-1]) + grid[i][j] 确保了我们能够找到从左上角到右下角的最小路径和。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!
关注我,获取更多算法题解和编程技巧!