Leetcode 题解 1102. 得分最高的路径
原题内容:
错误的思路
1.每次都选择下一步更大的值进行下去 这个思路也是我一开始就会想到的,但是一旦列出反例,就知道这个思路是错误的了。如下图:
正确的思路
那么正确的思路,应该是怎样的呢?
- 1.定义一个队列,将下一步可达的地方存入队列
- 2.每次取出队列中最大的值作为下一步要探索的地方
- 3.依次记录所有走过的位置中,最小的值作为结果 如果先单纯用文字直接描述的话,可能会有点难懂,这里可以先看看下面的图片看看正确的思路,会以怎样的过程走到终点。看下图流程:
代码(javascript语言)如下:
function Point(x, y, val) {
this.x = x;
this.y = y;
this.val = val;
}
/**
* @param {number[][]} grid
* @return {number}
*/
var maximumMinimumPath = function (grid) {
// 方向, 用于坐标上下左右的移动
let direction = [
[1, 0],
[0, 1],
[0, -1],
[-1, 0]
];
let m = grid.length,
n = grid[0].length,
i, j, x, y, k, ans = grid[0][0];
// 用于判断某个位置是否已经访问/展开过
let visited = new Array(m);
for (let i = 0; i < m; i++) {
visited[i] = new Array(n).fill(false);
}
visited[0][0] = true;
// 把第一个节点放入队列当中
let queue = [new Point(0, 0, grid[0][0])];
while (queue.length) {
// 每次都要记录一次最小值
ans = Math.min(ans, queue[0].val);
i = queue[0].x;
j = queue[0].y;
queue.splice(0, 1);
// 如果到了右下角,即:最后一个位置,直接返回结果
if (i == m - 1 && j == n - 1)
return ans;
// 向四个方向走
for (k = 0; k < 4; ++k) {
x = i + direction[k][0];
y = j + direction[k][1];
if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y]) {
let tempPoint = new Point(x, y, grid[x][y]);
// 这里需要将队列从大到小排序
for(let l = 0; l < queue.length; l++) {
if(tempPoint.val >= queue[l].val) {
queue.splice(l, 0, tempPoint);
break;
}
if(l === queue.length - 1) {
queue.push(tempPoint);
}
}
if(queue.length == 0) {
queue.push(tempPoint);
}
visited[x][y] = true;
}
}
}
return ans;
};
let grid = [
[5, 4, 5],
[1, 2, 6],
[7, 4, 6]
];
console.log(maximumMinimumPath(grid));
grid = [
[2, 2, 1, 2, 2, 2],
[1, 2, 2, 2, 1, 2]
];
console.log(maximumMinimumPath(grid));
grid = [
[3, 4, 6, 3, 4],
[0, 2, 1, 1, 7],
[8, 8, 3, 2, 7],
[3, 2, 4, 9, 8],
[4, 1, 2, 0, 0],
[4, 6, 5, 4, 3]
];
console.log(maximumMinimumPath(grid));