先使用dfs进行计算
往左走的到达右下角的值与往下走到达右下脚的值比较小的那个就是最终的结果
public int minPathSum(int[][] grid) {
if (grid.length == 1 && grid[0].length == 1){
return grid[0][0];
}
return dfs(grid, 0, 0);
}
private int dfs(int[][] grid, int x, int y){
if (x >= grid.length || y >= grid[0].length){
return Integer.MAX_VALUE;
}
if (x == grid.length-1 && y == grid[0].length-1){
return grid[x][y];
}
int left = dfs(grid, x + 1, y);
int right = dfs(grid, x, y + 1);
return Math.min(left,right) + grid[x][y];
}
对dfs进行记忆化搜索改造
使用一个二维数组将从该点出发的最短路径记录下来,避免重复计算
public int minPathSum(int[][] grid) {
if (grid.length == 1 && grid[0].length == 1){
return grid[0][0];
}
int [][] path = new int[grid.length][grid[0].length];
return dfs(grid, 0, 0, path);
}
private int dfs(int[][] grid, int x, int y, int [][] path){
if (x >= grid.length || y >= grid[0].length){
return Integer.MAX_VALUE;
}
if (path[x][y] > 0){
return path[x][y];
}
if (x == grid.length-1 && y == grid[0].length-1){
return grid[x][y];
}
int left = dfs(grid, x + 1, y, path);
int right = dfs(grid, x, y + 1, path);
int min = Math.min(left,right) + grid[x][y];
path[x][y] = min;
return min;
}
能写出上面的递归,就很容易根据递归公式,写出动态规划了
public int minPathSum(int[][] grid) {
int x = grid.length;
int y = grid[0].length;
int [][] dp = new int[x][y];
dp[x-1][y-1] = grid[x-1][y-1];
for (int i = x - 2; i>=0; i--){
dp[i][y-1] = dp[i + 1][y-1] + grid[i][y-1];
}
for (int i = y - 2; i>=0; i--){
dp[x-1][i] = dp[x-1][i+1] + grid[x-1][i];
}
for (int i = x - 2; i >= 0; i --){
for (int j = y - 2; j >= 0; j --){
dp[i][j] = Math.min(dp[i][j+1],dp[i+1][j]) + grid[i][j];
}
}
return dp[0][0];
}