原题
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
思路
解决DP问题,最重要的是找出状态转移方程,我们下面举一个例子,尝试找出本题的状态转移方程
第一步
对于grid[0][0]而言无论,如何行动,路径的和一定等于1
第二步
由于我们只能向下和向右走,所以。
当i = 0时,路径和一定等于grid[i][j] + grid[i][j - 1],因为我们只能往右走
当j = 0时,路径和一定等于grid[i][j] + grid[i -1][j],因为我们只能往下走
我们可以得到如下的grid
第三步
对于i !=0 && j !== 0的情况,我们到达此点的方式,可以从上面,也可以从左面。我们应该选择两种方式中和最小的方式
第n步 ……依次类推
通过上面的分析,我们可以获得如下状态转移方程, 接下来我们可以轻松列出我们的代码了
代码
/**
* @param {number[][]} grid
* @return {number}
*/
var minPathSum = function(grid) {
if (grid.length === 0) {
return 0
}
const dp = []
const w = grid[0].length
const h = grid.length
for (let i = 0; i < h; i++) {
for (let j = 0; j < w; j++) {
if (!dp[i]) {
dp[i] = []
}
let m, n
if (i === 0) {
m = j - 1 < 0 ? 0 : dp[i][j - 1]
n = grid[i][j]
dp[i][j] = m + n
continue
}
if (j === 0) {
m = i - 1 < 0 ? 0 : dp[i - 1][j]
n = grid[i][j]
dp[i][j] = m + n
continue
}
dp[i][j] = Math.min(
grid[i][j] + dp[i - 1][j],
grid[i][j] + dp[i][j - 1]
)
}
}
return dp[h - 1][w - 1]
};