法一
/**
* 动态规划
* 时间复杂度:O(m * n)
* 空间复杂度:O(m * n)
* (1)确定dp数组以及下标的含义
* dp[i][j]表示从(0,0)出发,到(i,j)的最小数字总和为dp[i][j]
* (2)确定递推公式
* dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j] // dp[i][j]只有从上方和左方这两个方向过来
* (3)确定dp数组如何初始化
* dp[0][0] = grid[0][0]
* dp[i][0] = dp[i - 1][0] + grid[i][0] // 0 < i < m
* dp[0][j] = dp[0][j - 1] + grid[0][j]; // 0 < j < m
* (4)确定遍历顺序
* dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了
*
* @param grid
* @return
*/
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
if (m == 0 || n == 0) {
return 0;
}
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j - 1] + grid[0][j];
}
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];
}
本地测试
/**
* 64. 最小路径和
*/
lay.showTitle(64);
Solution64 sol64 = new Solution64();
int[][] grid64 = new int[][]{{1, 3, 1}, {1, 5, 1}, {4, 2, 1}};
System.out.println(sol64.minPathSum(grid64));