持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
64. 最小路径和
来源:力扣(LeetCode)
链接: leetcode.cn/problems/mi…
给定一个包含非负整数的 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 == grid.length
- n == grid[i].length
- 1 <= m, n <= 200
- 0 <= grid[i][j] <= 100
解法
- 动态规划:路径相关的题目,可以使用BFS或者DFS进行解决,就是有些复杂。这里路径依赖于之前的状态,这里以动态规划的方法来解决。
动态规划:四个步骤:
- 问题定义
- 状态转移方程
- 初始条件和边界情况
- 确定计算顺序(自顶向下,还是自下向上)
问题定义: dp[i][j]表示走到位置(i, j)时候所获得的路径上的数字总和最小值
状态转移方程: 由于只能往右和向下走,那么到达(i,j)位置只可能是从左边或者上边得到
- dp[i][j] = min(dp[i][j-1], dp[i-1][j]) + grid[i][j]
这里如果不考虑权重的话,就不用加
grid[i][j]
初始化条件和边界条件
-
dp[0][0] = grid[0][0]
确定计算顺序: 这个是从下向上的方向计算即可
代码实现
动态规划
python实现
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
m = len(grid)
n = len(grid[0])
dp = grid[:]
# init first col only could be down
for i in range(1, m):
dp[i][0] = dp[i-1][0] + grid[i][0]
# init first row, only could be right
for j in range(1, n):
dp[0][j] = dp[0][j-1] + grid[0][j]
for i in range(1, m):
for j in range(1, n):
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
return dp[-1][-1]
c++实现
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp = grid;
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];
}
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];
}
};
复杂度分析
- 时间复杂度: m行n列
- 空间复杂度: