一、题目描述
二、题目翻译
给定一个二维网格,在某些条件A的限制下,请找出一条从起点到终点的路径,使得路径上的数字总和最小。
条件A:机器人每次只能向下或者向右移动一步。
三、再来点用例
四、思路讲解
我们以如下二维表格来进行分析:
其中,1是起点,9是终点。
以9的角度来看,能够到达9的路径有2个,分别是 8 和 6。但是这里会出现一个问题,我是取8 还是 6?
4.1、8还是6?
这里肯定会有人说,当然取6了,因为6更小,且符合题意。那如果是下面这样的二维网格呢?
那可就不是取6了,那得是取8,路径和才能最小,且符合题意(此时的路径集合:(0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2))
所以,经过上面的分析,我们会发现,取8还是取6,是由下面的思路决定的:
1、到达8的最小路径和,到达6的最新路径和,他俩谁小取谁。
2、最小路径和 有时并不等于 网格上的值。
那么,5、6、8的网格的分析思路一定是与9的网格的思路是一样的,因为他们都有一个共同的特点,那就是到达5、6、8、9这四个网格中的一个,都有2条路径。
那么我们照着这个思路可以写出如下代码:
var minPathSum = function (grid){
let xLength = grid.length;
let yLength = grid[0].length;
// 创建dp数组,用于存放二维网格中每个单元格被到达时的最小路径数。
let dp = new Array(xLength).fill(1).map(item => new Array(yLength).fill(1));
dp[0][0] = grid[0][0];
for (let x = 0; x < xLength; x++){
for (let y = 0; y < yLength; y++){
if (x > 0 && y > 0){
dp[x][y] = Math.min( dp[x-1][y], dp[x][y-1] ) + grid[x][y];
}
}
}
};
4.2、2和3网格如何取值?
无论是2还是3,我们发现根据题意,他们的入口只能有1个,就是一直向右。
以2为举例,2的最小路径和 == 1的网格值 + 2的网格值。
以3为举例,3的最小路径和 == 2的最小路径和 + 3的网格值。
这里依然会有一个问题,3的最小路径和 == 2的最小路径和 + 3的网格值。我们这里为什么取的是2的最小路径和,而不是2的网格值?
答案:因为网格值是不可信的,2的网格值有可能是任意值,只不过在我们的例子中,2网格值正好等于2,而2的最小路径和等于3。
基于上面的分析:我们补全剩余代码:
var minPathSum = function (grid){
let xLength = grid.length;
let yLength = grid[0].length;
// 创建dp数组,用于存放二维网格中每个单元格被到达时的最小路径数。
let dp = new Array(xLength).fill(1).map(item => new Array(yLength).fill(1));
dp[0][0] = grid[0][0];
for (let x = 0; x < xLength; x++){
for (let y = 0; y < yLength; y++){
if (x > 0 && y > 0){
dp[x][y] = Math.min( dp[x-1][y], dp[x][y-1] ) + grid[x][y];
} else if (x == 0 && y > 0){
// 横轴第0行
dp[x][y] = dp[x][y-1] + grid[x][y];
} else if (x > 0 && y == 0){
// 纵轴第0行
dp[x][y] = dp[x-1][y] + grid[x][y];
}
}
}
return d[xLength - 1][yLength - 1];
};
跑一下上面的代码,我们发现,得到的结果都是正确的。
五、最后
好啦,又到了文章结尾了,我们下期再见啦。