leetcode64. 最小路径和
给定一个包含非负整数的 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
最小路径和问题
题目分析
给定一个包含非负整数的网格 grid
,找到一条从左上角到右下角的最小路径和。每次只能向下或向右移动一步。
算法步骤
- 初始化一个二维数组
dp
,大小与grid
相同,用于存储从起点到每个位置的最小路径和。 - 初始化
dp[0][0]
为grid[0][0]
。 - 初始化第一行和第一列,将每个位置的值设置为它自己和它上方或左方位置的最小路径和之和。
- 遍历
grid
的其余部分,对于每个位置(i, j)
,将其路径和设置为它上方和左方位置路径和中的最小值加上它自己的值。 - 返回
dp[m-1][n-1]
,即从左上角到右下角的最小路径和。
算法流程
具体代码
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp(m, vector<int>(n, 0));
// 初始化 dp 数组的第一行和第一列
dp[0][0] = grid[0][0];
for (int i = 1; i < m; ++i) {
dp[i][0] = dp[i-1][0] + grid[i][0];
}
for (int j = 1; j < n; ++j) {
dp[0][j] = dp[0][j-1] + grid[0][j];
}
// 填充 dp 数组的其余部分
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
}
}
return dp[m-1][n-1];
}
};
算法分析
- 时间复杂度: O(m*n),需要遍历整个网格一次。
- 空间复杂度: O(m*n),需要存储整个动态规划数组
dp
。 - 易错点: 在初始化第一行和第一列时,需要正确计算每个位置的路径和。
相似题目
题目 | 链接 |
---|---|
120. 三角形最小路径和 | https://leetcode.cn/problems/triangle/ |
64. 最小路径和 | https://leetcode.cn/problems/minimum-path-sum/ |
322. 零钱兑换 | https://leetcode.cn/problems/coin-change/ |