描述
给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。
示例1
输入:
[[1,3,5,9],[8,1,3,4],[5,0,6,1],[8,8,4,0]]
返回值:
12
方法一:暴力递归:
因为是从左上角到右下角,只能向右或者向下,
可以使用递归,
把问题简化为:当前位置(i, j)和右边位置(i + 1, j)和下面位置(i, j + 1)之间的问题
base case:
当i == row - 1 && j == col - 1时,位于矩阵右下角,即为最终结果
当i == row - 1时,位于最后一行,此时只能向右走
当j == col - 1时,位于最右一行,此时只能向下走
当位于矩阵中间某个位置时(i, j),此时要判断右边位置(i + 1, j)和下面位置(i, j + 1)中的值谁大谁小
代码:
public int minPathSum(int matrix[][],int i,int j){
//如果(i,j)就是右下角的元素
if(i==matrix.length-1&&j==matrix[0].length-1){
return matrix[i][j];
}
//如果(i,j)在右边界上,只能向下走
if(j==matrix[0].length-1){
return matrix[i][j]+minPathSum(matrix,i+1,j);
}
//如果(i,j)在下边界上,只能向右走
if(i==matrix.length-1){
return matrix[i][j]+minPathSum(matrix,i,j+1);
}
int left=minPathSum(matrix,i,j+1);
int down=minPathSum(matrix,i+1,j);
return matrix[i][j]+Math.max(left,down);
}在这里插入代码片
方法二;动态规划
import java.util.Arrays;
public class Solution {
public int minPathSum(int[][] grid) {
if (grid == null) {
return 0;
}
int rowLen = grid.length;
int colLen = grid[0].length;
int[] res = new int[colLen + 1];
Arrays.fill(res, Integer.MAX_VALUE);
res[1] = 0;
for (int i = 1; i <= rowLen; i++) {
for (int j = 1; j <= colLen; j++) {
//当前点的最小路径和为 : 从左边和上边选择最小的路径和再加上当前点的值
//res[j]没更新之前就表示i-1行到第j个元素的最小路径和
//因为是从左往右更新,res[j-1]表示i行第j-1个元素的最小路径和
res[j] = Math.min(res[j], res[j - 1]) + grid[i - 1][j - 1];
}
}
return res[colLen];
}
}