题目链接
https://leetcode.com/problems/cut-off-trees-for-golf-event/
题意
给出一个 n * m 的地图,其中有包括树和障碍。从(0,0)开始出发,在避开障碍的情况下,需要按照树的高度从矮到高依次到达,问一共最少需要多少步。无法依次达到,则输出 -1。
思路
- 先对地图中的树的高度进行排序,得到总的路径。
- 对于路径中的每一个节点,将问题转变为从 A 点到 B 点的最短路程的子问题。
- 对每个子问题进行宽度搜索,将所有子问题的最短路程相加即可。当某个子问题无解时,则直接输出 -1
代码
// 宽搜,参数:Map,A.x,A.y,B.x,B.y
var calStep = function(forest, x1, y1, x2, y2) {
let vis = []; // 用来记录该位置是否访问过,避免重复递归
let h = forest.length;
let w = forest[0].length
for (let i = 0; i < h; i++) {
let tmp = [];
for (let j = 0; j < w; j++) {
tmp.push(0);
}
vis.push(tmp);
}
vis[x1][y1] = 1;
let q = [];
q.push({x: x1, y: y1, step: 0});
while(q.length > 0) {
let item = q.shift();
// 若已到达 B 点,返回步数
if (item.x === x2 && item.y === y2) {
return item.step;
}
// 对当前节点,若其上下左右节点合法,且未访问,则放入队列中待判
if (item.x-1 >= 0 && !vis[item.x - 1][item.y] && forest[item.x - 1][item.y]) {
vis[item.x - 1][item.y] = 1;
q.push({x: item.x - 1, y: item.y, step: item.step + 1});
}
if (item.x+1 < h && !vis[item.x + 1][item.y] && forest[item.x + 1][item.y]) {
vis[item.x + 1][item.y] = 1;
q.push({x: item.x + 1, y: item.y, step: item.step + 1});
}
if (item.y-1 >= 0 && !vis[item.x][item.y - 1] && forest[item.x][item.y - 1]) {
vis[item.x][item.y - 1] = 1;
q.push({x: item.x, y: item.y - 1, step: item.step + 1});
}
if (item.y+1 < w && !vis[item.x][item.y + 1] && forest[item.x][item.y + 1]) {
vis[item.x][item.y + 1] = 1;
q.push({x: item.x, y: item.y + 1, step: item.step + 1});
}
}
return -1;
}
/**
* @param {number[][]} forest
* @return {number}
*/
var cutOffTree = function(forest) {
let tree = [];
for (let i = 0; i < forest.length; i++) {
for (let j = 0; j < forest[i].length; j++) {
if (forest[i][j] !== 0) {
tree.push({val: forest[i][j], x: i, y: j});
}
}
}
// 对树的高度进行排序
tree.sort((a, b) => {
if (a.val < b.val) {
return -1;
}
return 1;
})
let result = 0;
for (let i = 0; i < tree.length; i++) {
if (i === 0) {
let step = calStep(forest, 0, 0, tree[i].x, tree[i].y);
if (step === -1) {
return -1;
}
result = result + step;
} else {
let step = calStep(forest, tree[i - 1].x, tree[i - 1].y, tree[i].x, tree[i].y);
if (step === -1) {
return -1;
}
result = result + step;
}
}
return result;
};