Rain water flows to neighboring cells with equal or lower height. The Pacific touches the top and left edges and the Atlantic the bottom and right. Return every cell that can flow to both oceans.
Same reverse idea with a queue: spread out from both oceans layer by layer.
1function pacificAtlantic(heights: number[][]): number[][] {2const m = heights.length, n = heights[0].length;3const bfs = (seeds: number[][]) => {4const ocean = heights.map((row) => row.map(() => false));5for (const [r, c] of seeds) ocean[r][c] = true;6const queue = [...seeds];7while (queue.length) {8const [r, c] = queue.shift()!;9for (const [dr, dc] of [[1, 0], [-1, 0], [0, 1], [0, -1]]) {10const x = r + dr, y = c + dc;11if (x < 0 || y < 0 || x >= m || y >= n || ocean[x][y]) continue;12if (heights[x][y] >= heights[r][c]) { ocean[x][y] = true; queue.push([x, y]); }13}14}15return ocean;16};17const cols = [...Array(n).keys()], rows = [...Array(m).keys()];18const pac = bfs([...cols.map((c) => [0, c]), ...rows.map((r) => [r, 0])]);19const atl = bfs([...cols.map((c) => [m - 1, c]), ...rows.map((r) => [r, n - 1])]);20const res: number[][] = [];21for (let r = 0; r < m; r++)22for (let c = 0; c < n; c++) if (pac[r][c] && atl[r][c]) res.push([r, c]);23return res;24}
| 1 | 2 | 2 | 3 | 5 |
| 3 | 2 | 3 | 4 | 4 |
| 2 | 4 | 5 | 3 | 1 |
| 6 | 7 | 1 | 4 | 5 |
| 5 | 1 | 1 | 2 | 4 |
Start from every Pacific border cell and climb to equal-or-higher neighbors.
Space: play/pause · ←/→: step