给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。

给定一个
的网格,每个单元格包含一个非负整数,表示从起点
到终点
的路径的代价。你可以仅向右或向下移动。我们的目标是找到一条路径, 使得路径上的数字之和最小。
在这个问题中,我们需要考虑如何从左上角移动到右下角。每个位置的最小路径和可以通过其上方或左方的路径和来计算:
,则其最小路径和可以表示为:
其中, dp
表示到达 (
的最小路径和。
我们需要一个二维数组
,其中
表示到达
的最小路径和。我们可以直接在原始 grid 数组上进行修改,以节省空间。
从
开始填充 dp 数组,直到
。
即为所求的最小路径和。
由于计算每个位置的最小路径和仅依赖于上方和左方的位置,我们可以使用一维数组代替二维数组,从而降低空间复杂度。
,需要遍历整个网格。
的空间来存储当前行的路径和。
以上就是最小路径和问题的基本思路。
class Solution:
def minPathSum(self, grid: list[list[int]]) -> int:
if not grid or not grid[0]:
return 0
rows, cols = len(grid), len(grid[0])
# 用于存储当前行的最小路径和
dp = [0] * cols
# 初始化第一行
for j in range(cols):
dp[j] = grid[0][j] if j == 0 else dp[j-1] + grid[0][j]
# 遍历每一行
for i in range(1, rows):
# 初始化当前行的第一列
dp[0] += grid[i][0]
# 遍历当前行
for j in range(1, cols):
dp[j] = grid[i][j] + min(dp[j], dp[j-1])
# 返回右下角的最小路径和
return dp[-1]来存储当前行的最小路径和。
数组中的值,最终返回右下角的值。
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
if (grid.empty() || grid[0].empty()) return 0;
int rows = grid.size();
int cols = grid[0].size();
// 用于存储当前行的最小路径和
vector<int> dp(cols, 0);
// 初始化第一行
for (int j = 0; j < cols; ++j) {
dp[j] = grid[0][j] + (j > 0 ? dp[j - 1] : 0);
}
// 遍历每一行
for (int i = 1; i < rows; ++i) {
dp[0] += grid[i][0]; // 当前行的第一列
// 遍历当前行
for (int j = 1; j < cols; ++j) {
dp[j] = grid[i][j] + min(dp[j], dp[j - 1]);
}
}
// 返回右下角的最小路径和
return dp.back();
}
};