64. 最小路径和
自顶向下-动态规划解法
- 每次走一步,路径和都会发生变化,那么变化的就是状态也就是路径和
- 我们定义dp[i][j]为走到(i,j)位置的最小路径和
- 那么首先base case 就是i = 0 j = 0的位置直接返回grid[0][0]
- 然后还需要判断是否越界
- 定义一个备忘录 记录子问题的解 初始化全部为-1
- 然后再dp的过程中首先判断这个子问题能不能再备忘录中查找到
- 然后计算下一步
class Solution {
int[][] mem;
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
mem = new int[m][n];
for(int [] row:mem){
Arrays.fill(row,-1);
}
return dp(grid,m - 1,n - 1);
}
int dp(int[][] grid, int i,int j){
if(i == 0 && j == 0){
return grid[0][0];
}
if(i < 0 || j < 0){
return Integer.MAX_VALUE;
}
if(mem[i][j] != -1){
return mem[i][j];
}
mem[i][j] = Math.min(dp(grid,i - 1,j),dp(grid,i,j - 1)) + grid[i][j];
return Math.min(dp(grid,i - 1,j),dp(grid,i,j - 1)) + grid[i][j];
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
自底向上进行递归
- base case dp[0][0] = grid[0][0];
- 另外对于第一行和第一列元素进行初始化
- 之后遍历 状态转移 自底向上
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][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++){
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
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];
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32