dp[ i ] [ j ] 含义
- 从左上角点走到( i, j )点的最短路径和

public int minPathSum(int[][] grid) {int N = grid.length;int M = grid[0].length;int[][] dp = new int[N][M];dp[0][0] = grid[0][0];for (int j = 1; j < M; j++) {dp[0][j] = dp[0][j - 1] + grid[0][j];}for (int i = 1; i < N; i++) {dp[i][0] = dp[i - 1][0] + grid[i][0];}for (int i = 1; i < N; i++) {for (int j = 1; j < M; j++) {dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];}}return dp[N - 1][M - 1];}
- 可以空间压缩


然后我在发现在填dp表的时候,我只需要我上一行的值即可
因此用一个一维数组


//空间压缩版本
public int minPathSum2(int[][] grid) {
int N = grid.length;
int M = grid[0].length;
// 其实应该是一张二维表,但是用了空间压缩技巧
int[] dp = new int[M];
// dp数组变成,想象中二维表的第0行数据
// m : 3 2 1 6 3 5 6 12
dp[0] = grid[0][0];
for (int j = 1; j < M; j++) {
dp[j] = dp[j - 1] + grid[0][j];
}
for (int i = 1; i < N; i++) {
//dp此时是想象中二维表的第i-1行数据
// 想更新成,想象中二维表的第i行数据
// dp[0]
dp[0] = dp[0] + grid[i][0];
for (int j = 1; j < M; j++) {
dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
}
}
return dp[M - 1];
}
- 总结,只要动态规划是依赖于自己的临近位置,都可以做空间压缩
