题目描述
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[[1,3,1],
[1,5,1],
[4,2,1]
]输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
思路分析
主体思路都是,下一个位置值=当前位置值+Math.min(往下,往右),在最下行只能往右,在最右列只能往下。
- 暴力递归,时间通不过…
- 动规做法。简单的动规,状态转移和base case就是上面说的情况。
- 因为从右下角往左上角做,所以可以不用新建数组做备忘录,直接用原来的数组做备忘库,减少空间复杂度。(力扣上并没有,时间还多了2ms,小声bb)
代码实现
/**
* 暴力递归,时间超时
*
* @param grid
* @return
*/
public int minPathSum(int[][] grid) {
if (grid == null) {
return 0;
}
int row = grid.length;
int col = grid[0].length;
return process(grid, row, 0, col, 0);
}
public int process(int[][] grid, int row, int curRow, int col, int curCol) {
if (curRow == row - 1 && curCol == col - 1) {
return grid[curRow][curCol];
}
if (curRow == row) {
return Integer.MAX_VALUE;
}
if (curCol == col) {
return Integer.MAX_VALUE;
}
return grid[curRow][curCol] + Math.min(process(grid, row, curRow + 1, col, curCol),
process(grid, row, curRow, col, curCol + 1));
}
/**
* 简单动规,建立一个备忘录
*
* @param grid
* @return
*/
public int minPathSum1(int[][] grid) {
if (grid == null) {
return 0;
}
int row = grid.length - 1;
int col = grid[0].length - 1;
int[][] dp = new int[row + 1][col + 1];
for (int i = row; i >= 0; i--) {
for (int j = col; j >= 0; j--) {
if (i == row && j != col) {
dp[i][j] = grid[i][j] + dp[i][j + 1];
} else if (i != row && j == col) {
dp[i][j] = grid[i][j] + dp[i + 1][j];
} else if (i != row && j != col) {
dp[i][j] = grid[i][j] + Math.min(dp[i + 1][j], dp[i][j + 1]);
} else {
dp[i][j] = grid[i][j];
}
}
}
return dp[0][0];
}
/**
* 用原本的数组作为备忘录
* @param grid
* @return
*/
public int minPathSum2(int[][] grid) {
if (grid == null) {
return 0;
}
for (int i = grid.length - 1; i >= 0; i--) {
for (int j = grid[0].length - 1; j >= 0; j--) {
if (i == grid.length - 1 && j != grid[0].length - 1)
grid[i][j] = grid[i][j] + grid[i][j + 1];
else if (j == grid[0].length - 1 && i != grid.length - 1)
grid[i][j] = grid[i][j] + grid[i + 1][j];
else if (j != grid[0].length - 1 && i != grid.length - 1)
grid[i][j] = grid[i][j] + Math.min(grid[i + 1][j], grid[i][j + 1]);
}
}
return grid[0][0];
}