题目描述
给定一个包含非负整数的 m x n 网格 grid,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明: 每次只能向下或者向右移动一步。
示例:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
核心思路
本题是典型的动态规划问题。我们可以按照动态规划的几个核心步骤来进行分析:
1. 定义状态
设 dp[i][j] 为到达位置 (i, j) 的最小路径和。
2. 状态转移方程
从左上角 (0, 0) 开始,移动到 (i, j) 只能从上方 (i-1, j) 或左方 (i, j-1) 移动过来。
因此,状态转移方程为:
dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])
3. 边界条件
需要注意边界情况,即第一行和第一列:
当 i = 0 时(第一行):只能从左边移动,dp[0][j] = dp[0][j-1] + grid[0][j]
当 j = 0 时(第一列):只能从上边移动,dp[i][0] = dp[i-1][0] + grid[i][0]
4. 初始化
起点的路径和即为它本身的值:
dp[0][0] = grid[0][0]
5. 计算与结果
通过双重循环遍历整个 grid,根据上述方程填充 dp 数组。
最终结果为 dp[m-1][n-1],即到达右下角的最小路径和。
______
代码实现 (Java)
以下是基于上述思路的完整 Java 代码实现:
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
// 创建一个二维数组 dp,用于存储到达每个点的最小路径和
int[][] dp = new int[m][n];
// 初始化起点
dp[0][0] = grid[0][0];
// 填充第一行 (只能从左边移动)
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j - 1] + grid[0][j];
}
// 填充第一列 (只能从上边移动)
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
// 填充剩余的 dp 数组
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
// 当前点的最小路径和 = 当前点的值 + 上方和左方的最小路径和
dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j - 1]);
}
}
return dp[m - 1][n - 1];
}
}

283

被折叠的 条评论
为什么被折叠?



