Skip to content

Commit 5b323c8

Browse files
committed
Added 1 JS solution for problem 417
1 parent 1d5cfd6 commit 5b323c8

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//////////////////////////////////////////////////////////////////////////////
2+
// Depth First Search (DFS)
3+
// Time: O(m*n)
4+
// Space: O(m*n)
5+
// You can implement either Depth First Search (DFS) or Breadth First Search
6+
// (BFS). The only noticeable impact is the performance cost of the BFS queue
7+
// is higher than the DFS call stack. Also note if you are implementing BFS
8+
// that you should terminate the search at the dequeue call if the coordinates
9+
// signify that the cell has already been traversed as well as terminating the
10+
// search before the enqueue call at each of the four supplemental directions.
11+
//////////////////////////////////////////////////////////////////////////////
12+
13+
class Drains {
14+
constructor(west = false, east = false) {
15+
this.west = west;
16+
this.east = east;
17+
}
18+
}
19+
20+
/**
21+
* @param {number[][]} heights
22+
* @return {number[][]}
23+
*/
24+
function pacificAtlantic(heights) {
25+
26+
const rowLen = heights.length;
27+
const colLen = heights[0].length;
28+
const lastRow = rowLen - 1;
29+
const lastCol = colLen - 1;
30+
const drainage = new Array(rowLen);
31+
const drainsBoth = [];
32+
33+
for (let r = 0; r < rowLen; ++r) {
34+
drainage[r] = new Array(colLen);
35+
for (let c = 0; c < colLen; ++c) {
36+
drainage[r][c] = new Drains();
37+
}
38+
}
39+
40+
for (let r = 0; r < rowLen; ++r) {
41+
markDrainage(r, 0, true);
42+
markDrainage(r, lastCol);
43+
}
44+
for (let c = 0; c < colLen; ++c) {
45+
markDrainage(0, c, true);
46+
markDrainage(lastRow, c);
47+
}
48+
49+
return drainsBoth;
50+
51+
/**
52+
* @param {number} r
53+
* @param {number} c
54+
* @param {boolean=} west = `false`
55+
* @param {number=} prev = `-Infinity`
56+
* @return {void}
57+
*/
58+
function markDrainage(r, c, west = false, prev = -Infinity) {
59+
60+
if (!inBounds(r, c)
61+
|| heights[r][c] < prev
62+
|| (west && drainage[r][c].west)
63+
|| (!west && drainage[r][c].east)
64+
) {
65+
return;
66+
}
67+
68+
const drains = drainage[r][c];
69+
const height = heights[r][c];
70+
71+
if (west) {
72+
drains.west = true;
73+
} else {
74+
drains.east = true;
75+
}
76+
77+
if (drains.west && drains.east) {
78+
drainsBoth.push([ r, c ]);
79+
}
80+
81+
markDrainage(r - 1, c, west, height);
82+
markDrainage(r + 1, c, west, height);
83+
markDrainage(r, c - 1, west, height);
84+
markDrainage(r, c + 1, west, height);
85+
}
86+
87+
/**
88+
* @param {number} r
89+
* @param {number} c
90+
* @return {boolean}
91+
*/
92+
function inBounds(r, c) {
93+
return r >= 0 && c >= 0 && r < rowLen && c < colLen;
94+
}
95+
}

0 commit comments

Comments
 (0)