问题描述
问题分析
- 该题和 LeetCode 120. Triangle 一样,是用动态规划求解最值问题,求解路径最小和问题。只不过120是三角形,可以说比该题稍微麻烦一点吧。
- 同样是先从递归入手,然后到动态规划,然后是动态规划的空间优化。
- 关于空间优化,因为
dp[i][j]
只依赖于 dp[i + 1][j]
与 dp[i][j + 1]
,那么同样可用一个数组滚动更新,来取代二维数组,只是要注意,是从右向左更新!!!注意顺序!!!
经验教训
- 注意动态规划时如何设计矩阵大小问题,该题也可以让dp再多加一行,多加一列,值全是
Integer.MAX_VALUE
,然后更新即可。
代码实现
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {
return 0;
}
return getMinPathSum(grid, 0, 0);
}
public int getMinPathSum (int[][] grid, int i, int j) {
if (i == grid.length - 1 && j == grid[0].length - 1) {
return grid[i][j];
}
if (i == grid.length || j == grid[0].length) {
return Integer.MAX_VALUE;
}
return grid[i][j] + Math.min(getMinPathSum(grid, i + 1, j), getMinPathSum(grid, i, j + 1));
}
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {
return 0;
}
int row = grid.length;
int col = grid[0].length;
int[][] dp = new int[row][col];
dp[row - 1][col - 1] = grid[row - 1][col - 1];
for(int j = col - 2; j >= 0; --j) {
dp[row - 1][j] = dp[row - 1][j + 1] + grid[row - 1][j];
}
for (int i = row - 2; i >= 0; --i) {
dp[i][col - 1] = dp[i + 1][col - 1] + grid[i][col - 1];
for (int j = col - 2; j >= 0; --j) {
dp[i][j] = grid[i][j] + Math.min(dp[i + 1][j], dp[i][j + 1]);
}
}
return dp[0][0];
}
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {
return 0;
}
int row = grid.length;
int col = grid[0].length;
int[] dp = new int[col];
dp[col - 1] = grid[row - 1][col - 1];
for(int j = col - 2; j >= 0; --j) {
dp[j] = dp[j + 1] + grid[row - 1][j];
}
for (int i = row - 2; i >= 0; --i) {
dp[col - 1] = dp[col - 1] + grid[i][col - 1];
for (int j = col - 2; j >= 0; --j) {
dp[j] = grid[i][j] + Math.min(dp[j], dp[j + 1]);
}
}
return dp[0];
}