题目
题解
水只会往两个方向流动,一个是低处,一个是水平处。不同与其他深度遍历,其他的深度遍历都是从数组挨个开始的。而这次需要从数组的四条边往里面深度优先搜索。这是为什么?小岛里的水想要流向大海,那吗小岛内就需要有个高点,这样水才能向下流,找这个点很难,但是它最后的出水口肯定在岛的四周,也就是数组的四条边。我们假设从岛的四周一点点探寻,寻找能所有能流进太平洋与能流进大西洋的路线,当路线上点重合的时候就是既能流进太平洋又能流进大西洋的路线,这也是我们要找的答案,就像是顺藤摸瓜,从岛的四周开始往岛内部探索
,
/*** @param {number[][]} heights* @return {number[][]}*/var pacificAtlantic = function (heights) {// 行的宽度const rLen = heights.length;// 列的宽度const cLen = heights[0].length;// 矩阵,与给定的数组相对应,当某一项为true说明能流进太平洋let canReachP = new Array(rLen);// 矩阵,与给定的数组相对应,当某一项为true说明能流进大西洋let canReachA = new Array(rLen);// 为矩阵添加初始值, 每一项的初始值都是falsefor(let r = 0; r < rLen; r++) {canReachA[r] = new Array(cLen).fill(false);canReachP[r] = new Array(cLen).fill(false);}// 存放结果的数组const result = [];// dfsconst dfs = (canReachArr, row, col) => {// 水流的方向const direction = [-1, 0, 1, 0, -1];// 当为true 说明水流经过这里if(canReachArr[row][col]) {return;}// 将对应的矩阵的对应点改为true 说明水流过这里canReachArr[row][col] = true;// 水流的下一个位置for(let i = 0; i < 4; i++) {let x = row + direction[i];let y = col + direction[i + 1];if(x >= 0 && x < rLen && y >= 0 && y < cLen && heights[row][col] <= heights[x][y]) {dfs(canReachArr, x, y)}}}// 水想从小岛流出来,那吗岸边会是小岛最低处// 从小岛最左面和最右面开始寻找上游的终点for(let r = 0; r < rLen; r++) {dfs(canReachP, r, 0);dfs(canReachA, r, cLen - 1);}// 从小岛最下面和最上面寻找上游的的终点for(let c = 0; c < cLen ; c++) {dfs(canReachA, rLen - 1, c);dfs(canReachP, 0, c);}// 找到那些流向太平洋与大西洋的水流的共同点for(let r = 0; r < rLen; r++) {for (let c = 0; c < cLen; c++) {if (canReachA[r][c] && canReachP[r][c]) {result.push([r, c]);}}}return result};

