我看了一下题解,基本都是从边界往高处流,确实简单很多。
但是我做题的时候,思路就是陷入从高往低处流的解法上。
/**
* @param {number[][]} heights
* @return {number[][]}
*/
var pacificAtlantic = function (heights) {
let ret = [];
let n = heights.length;
let meno = Array(n).fill(-1).map(() => Array(n).fill(-1));
let visited = Array(n).fill(false).map(() => Array(n).fill(false));
//! 疑问2:会死循环,因为从高往低流,相同值又会返回来遍历导致死循环,请问如何解决?
function dfsLT(heights, x, y) {
let left = top = true;
//left
for (let i = y; i >= 1; i--) {
if (heights[x][i - 1] > heights[x][i]) {
left = false;
break;
} else if (heights[x][i - 1] === heights[x][i]) {
left = dfs(heights, x, i - 1);
if (!left) {
break;
}
}
}
//top
for (let i = x; i >= 1; i--) {
if (heights[i - 1][y] > heights[i][y]) {
top = false;
break;
} else if (heights[i - 1][y] === heights[i][y]) {
top = dfs(heights, i - 1, y);
if (!top) {
break;
}
}
}
return left || top;
}
function dfsRB(heights, x, y) {
let right = bottom = true;
//right
for (let i = y; i < n - 1; i++) {
if (heights[x][i + 1] > heights[x][i]) {
right = false;
break;
} else if (heights[x][i + 1] === heights[x][i]) {
right = dfs(heights, x, i + 1);
if (!right) {
break;
}
}
}
//bottom
for (let i = x; i < n - 1; i++) {
if (heights[i + 1][y] > heights[i][y]) {
bottom = false;
break;
} else if (heights[i + 1][y] === heights[i][y]) {
bottom = dfs(heights, i + 1, y);
if (!bottom) {
break;
}
}
}
return right || bottom;
}
/* 判断此位置:是否可以流向左上&右下 */
function dfs(heights, x, y) {
if (meno[x][y] !== -1) {
return meno[x][y];
}
//! 疑问1: visited 已访问过,不管返回ture or false 都是不对的,因为无法确认此位置是否可以往下流。请问如何解决?
if (visited[x][y]) {
return false;
}
visited[x][y] = true;
let lt = rb = true;
do {
lt = dfsLT(heights, x, y);
if (!lt) {
break;
}
rb = dfsRB(heights, x, y);
} while (false);
meno[x][y] = lt && rb;
visited[x][y] = false;
return ret;
}
for (let x = 0; x < n; x++) {
for (let y = 0; y < n; y++) {
let res = dfs(heights, x, y);
if (res) {
ret.push([x, y]);
}
}
}
return ret;
};
代码中的2个疑问,麻烦老师解答一下。
如果我的思路错了,麻烦老师提供一个正向解题的思路,谢谢。