给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例 1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:
输入:grid = [[1,2,3],[4,5,6]]
输出:12
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j] <= 100
1.使用记忆化搜索:
class Solution { public int minPathSum(int[][] grid) { int[][] cache = new int[grid.length][grid[0].length]; for (int i =0; i < cache.length; i++) { for (int j = 0; j < cache[i].length; j++) { cache[i][j] = -1; } } return dfs(0,0, grid, cache); } public int dfs(int row, int col, int[][] grid, int[][] cache) { if (row == grid.length - 1 && col == grid[0].length - 1) { return grid[row][col]; } if (cache[row][col] != -1) { return cache[row][col]; } int cur = grid[row][col]; int right = 0; if (col + 1 < grid[0].length) { right = dfs(row, col+1, grid, cache); } else {//不能向下走,返回向右走的值 cache[row][col] = cur + dfs(row+1, col, grid, cache); return cache[row][col]; } int down = 0; if (row + 1 < grid.length) { down = dfs(row+1, col, grid, cache); } else {//不能向右走,返回向下走的值 cache[row][col] = cur + dfs(row, col+1, grid, cache); return cache[row][col]; } //取向下走和向右走的最小值 cache[row][col] =Math.min( cur + right, cur + down); return cache[row][col]; } }
2.动态规则
class Solution {
public int minPathSum(int[][] grid) {
int[][] arr = new int[grid.length][grid[0].length];
arr[0][0] = grid[0][0];
for (int i = 1; i < arr[0].length; i++) {
arr[0][i] = arr[0][i-1] + grid[0][i];
}
for (int i = 1; i < arr.length; i++) {
arr[i][0] = arr[i-1][0] + grid[i][0];
}
for (int row = 1; row < arr.length; row++) {
for (int col = 1; col < arr[0].length; col++) {
arr[row][col] = grid[row][col] + Math.min(arr[row][col-1], arr[row-1][col]);
}
}
return arr[grid.length-1][grid[0].length-1];
}
}