64_最小路径和[MEDIUM]
约 466 字大约 2 分钟
2026-03-20
给定一个包含非负整数的 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 x n网格 grid ,可以用数组grid[n][m]表示n表示有多少行,m表示有多少列grid[0][m]表示第一行 ,grid[n][0]表示第一列
要到达第 n 行第 m 列,只能是从其上方(n 行 m-1 列)或其左方( n-1 行 m 列)过来
动态规划
- 定义状态:
dp[n-1][m-1]就是到达第 n 行第 m 列的最小数字和 - 基础情况:
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] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
- 对于首行,只能从左边过来:
Java 实现
public int minPathSum(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
int[][] dp = new int[n][m];
dp[0][0] = grid[0][0];
// 初始化首行
for (int j = 1; j < m; j++){
dp[0][j] = dp[0][j-1] + grid[0][j];
}
// 初始化首列
for (int i = 1; i < n; i++){
dp[i][0] = dp[i-1][0] + grid[i][0];
}
// 剩余部分
for (int i = 1; i < n; i++){
for (int j = 1; j < m; j++){
dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1]) + grid[i][j];
}
}
return dp[n-1][m-1];
}