1.题目描述
给定一个包含非负整数的 *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.lengthn == grid[i].length1 <= m, n <= 2000 <= grid[i][j] <= 100
Tips: 力扣地址:leetcode-cn.com/problems/mi…
2. 思路分析
总体的思路就使用动态规划来解题。从左上角到右下角,那么只能往右或者往下走。从左上角到右下角路径是唯一的,因此每个元素对应的最小路径和即为对应的路径上的数字总和。也就是前面步骤和最小,下一步选择最小的就是总的最小。创建二维数组 \textit{dp}dp,与原始网格的大小相同,\textit{dp}[i][j]dp[i][j] 表示从左上角出发到 (i,j)(i,j) 位置的最小路径和。这里会有三种情况:
- 当 i>0 且 j=0 时,dp[i][0]=dp[i−1][0]+grid[i][0], 这个表示只能往下走,这种只有只用情况
- 当 i=0 且 j>0 时,dp[0][j]=dp[0][j-1]+grid[0][j], 这个表示只能往右边走,这种只有只用情况
- 当 i>0 且 j>0 时,dp[i][j]=min(dp[i][j-1],dp[i-1][j])+grid[i][j], 取往右走和往下走的最小值,然后加上grid[i][j]这个就是最小的,记录在定义的dp[i][j]中
3. AC代码
class Solution {
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
}
int x = grid.length;
int y = grid[0].length;
int[][] sum = new int[x ][y];
sum[0][0] = grid[0][0];
for (int i = 1; i < x; i++) {
sum[i][0] = sum[i - 1][0] + grid[i][0]; //一直往右的情况
}
for (int j = 1; j < y; j++) {
sum[0][j] = sum[0][j - 1] + grid[0][j]; //一直往下的情况
}
for(int i = 1; i < x; ++i){//往下走
for(int j = 1; j < y; ++ j){ //往右走
sum[i][j] = Math.min(sum[i][j-1],sum[i-1][j]) + grid[i][j];
}
}
return sum[x-1][y-1];
}
}
提交代码检验正确性:
完全正确
4. 总结
这道题主要考察的可以说是如何使用动态规划解题将大的问题解决成一个小的步骤,只需要用动态规划的实现写出动态方程式就能迎刃而解。解题的关键:
- 状态转移方程
- 特殊值的考虑
我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢