解题思路
本题为典型的动态规划
第一步:构造 二维dp
从左上角走到右下角,不走回头路,所以只能走下和右
设置二维dp,其值含义:走到当前位置所需要的的最小路径和
dp[i][j] = min(dp[i][j-1], dp[i-1][j]) + grid[i][j];
初始化:
(i == 0) dp[0][j] = dp[0][j-1] + grid[i][j], 0 <= j < col
(j == 0) dp[i][0] = dp[i-1][j] + grid[i][j], 0 <= i < row
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
}
int row = grid.length, col = grid[0].length;
int[][] dp = new int[row][col];
dp[0][0] = grid[0][0];
for (int i = 1; i < row; i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
for (int j = 1; j < col; j++) {
dp[0][j] = dp[0][j - 1] + grid[0][j];
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
return dp[row - 1][col - 1];
}
第二步:压缩状态 实现一维dp
利用滚动数组将第一维删掉,保留第二维
-
从第一行开始
当前位置只能从左边走过来 dp[j] = dp[j-1] + grid[0][j],0 <= j <= col -
第二行及以后
(1) j == 0,只能从上面走下来。
dp[0] += grid[i][j]
(2) 1 <= j < col,从上或左走到当前位置
dp[j] = min(dp[j-1], dp[j]) + grid[i][j]
dp[j-1]是左边的,dp[j]是上边的
public int minPathSum(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
}
int row = grid.length, col = grid[0].length;
int[] dp = new int[col];
dp[0] = grid[0][0];
for (int j = 1; j < col; j++) {
dp[j] = dp[j - 1] + grid[0][j];
}
for (int i = 1; i < row; i++) {
for (int j = 0; j < col; j++) {
if (j == 0) {
dp[j] += grid[i][j];
} else {
dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
}
}
}
return dp[col - 1];
}