给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
思路:
和前两篇博客的问题类似 每一个位置都是由同一行左边或者上一行相同位置得到
贴代码吧
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
for (int i = 1; i < n; i++) {
dp[0][i] = grid[0][i] + dp[0][i - 1];
}
for (int i = 1; i < m; i++) {
dp[i][0] = grid[i][0] + dp[i - 1][0];
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
return dp[m - 1][n - 1];
}
改成一维的动态规划
和之前博客总结的一样 从前往后的更新 每一个位置更新完了要给同行下一个位置使用
//改成一维
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int m = grid.length;
int n = grid[0].length;
int[] dp = new int[n];
dp[0]=grid[0][0];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) { //需要从前往后遍历 每一个位置更新完了要给同行下一个位置
if (i==0&&j==0) { //[0][0]位置
continue;
}else if (i==0&&j!=0) { //第一行其他位置
dp[j]=dp[j-1]+grid[i][j];
}else if (j==0) {
dp[j]=dp[j]+grid[i][j]; //等于上一行相同位置+当前值
}else {
dp[j] = Math.min(dp[j], dp[j - 1]) + grid[i][j];
}
}
}
return dp[n - 1];
}