小学都能看懂的题解 | #矩阵的最小路径和#
要解决这个问题,我们可以使用动态规划的方法来找出从左上角到右下角的最小路径和。以下是详细的代码实现和解释。
问题描述
给定一个 n x m
的矩阵,我们要找到从左上角到右下角的路径,使得路径上的所有数字之和最小。机器人每次只能向右或向下移动。
解决方案
我们可以使用一个二维数组 dp
来存储到达每个位置的最小路径和。然后我们根据当前位置的路径和更新下一个位置的值。
代码实现
public class MinimumPathSum {
public int minPathSum(int[][] grid) {
// 获取矩阵的行数和列数
int n = grid.length;
int m = grid[0].length;
// 创建一个二维数组dp,用于存储到达每个格子的最小路径和
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]; // 第一列只能从上面走
}
// 填充dp数组
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];
}
public static void main(String[] args) {
MinimumPathSum mps = new MinimumPathSum();
int[][] grid1 = {{1, 3, 5, 9}, {8, 1, 3, 4}, {5, 0, 6, 1}, {8, 8, 4, 0}};
System.out.println(mps.minPathSum(grid1)); // 输出: 12
int[][] grid2 = {{1, 2, 3}, {1, 2, 3}};
System.out.println(mps.minPathSum(grid2)); // 输出: 7
}
}
代码解释
-
获取矩阵的大小:
int n = grid.length; int m = grid[0].length;
这里我们获取矩阵的行数
n
和列数m
。 -
创建动态规划数组:
int[][] dp = new int[n][m];
dp[i][j]
用来表示到达(i, j)
的最小路径和。 -
初始化起点和第一行:
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]; // 当前格子的路径和 } }
对于每个位置
(i, j)
,我们取上面(i-1, j)
和左边(i, j-1)
的最小路径和,然后加上当前格子的值。 -
返回结果:
return dp[n - 1][m - 1];
最后返回右下角的路径和,即为我们需要的最小路径和。
时间复杂度
- 这个算法的时间复杂度是 O(n * m),因为我们需要遍历整个矩阵一次。
希望这篇文章对你有帮助👍。
#题解#小学生都能看懂的算法 文章被收录于专栏
主要面向小白的算法文章。以小学生都能看懂为目标而编写,顺便巩固下自己。