Skip to content

Commit f07e96e

Browse files
committed
Refactor dynamic programming approach of Trapping Rain Water problem.
1 parent 340a71b commit f07e96e

File tree

1 file changed

+31
-71
lines changed

1 file changed

+31
-71
lines changed

src/algorithms/uncategorized/rain-terraces/dpRainTerraces.js

+31-71
Original file line numberDiff line numberDiff line change
@@ -5,81 +5,41 @@
55
* @return {number}
66
*/
77
export default function dpRainTerraces(terraces) {
8-
/*
9-
* STEPS
10-
*
11-
* 1. Find the highest terraces on the left and right side of the elevation map:
12-
* e.g. for [0, 2, 4, 3, 4, 2, 4, 0, 8, 7, 0] we would have leftMax = 4 and rightMax = 8.
13-
* This is because water will "trail off" the sides of the terraces.
14-
*
15-
* 2. At this point, we are essentially dealing with a new map: [4, 3, 4, 2, 4, 0, 8].
16-
* From here, we loop through the map from the left to the right if leftMax < rightMax
17-
* (otherwise we move from right to left), adding water as we go unless we reach a value
18-
* that is greater than or equal to leftMax or rightMax.
19-
* e.g. [4, 3, 4, 2, 4, 0, 8]
20-
* ^
21-
* water = water + (leftMax - 3) = 1
22-
*
23-
* or if the terrace array was reversed:
24-
* e.g. [8, 0, 4, 2, 4, 3, 4]
25-
* ^
26-
* water = water + (rightMax - 3) = 1
27-
*
28-
* 3. Again, we've essentially shortened the map: [4, 2, 4, 0, 8].
29-
* Now we repeat the above steps on the new array.
30-
*
31-
* Next Iteration:
32-
* [4, 2, 4, 0, 8]
33-
* ^
34-
* water = water + (leftMax - 2) = 3
35-
*
36-
* Next Iteration:
37-
* [4, 0, 8]
38-
* ^
39-
* water = water + (leftMax - 0) = 7
40-
*
41-
* 4. Return result: 7
42-
*/
43-
let leftIndex = 0;
44-
let rightIndex = terraces.length - 1;
45-
46-
let leftMaxLevel = 0;
47-
let rightMaxLevel = 0;
48-
498
let waterAmount = 0;
509

51-
while (leftIndex < rightIndex) {
52-
// Loop to find the highest terrace from the left side.
53-
while (leftIndex < rightIndex && terraces[leftIndex] <= terraces[leftIndex + 1]) {
54-
leftIndex += 1;
55-
}
56-
57-
leftMaxLevel = terraces[leftIndex];
58-
59-
// Loop to find the highest terrace from the right side.
60-
while (rightIndex > leftIndex && terraces[rightIndex] <= terraces[rightIndex - 1]) {
61-
rightIndex -= 1;
62-
}
63-
64-
rightMaxLevel = terraces[rightIndex];
65-
66-
// Determine which direction we need to go.
67-
if (leftMaxLevel < rightMaxLevel) {
68-
// Move from left to right and collect water.
69-
leftIndex += 1;
10+
// Init arrays that will keep the list of left and right maximum levels for specific positions.
11+
const leftMaxLevels = new Array(terraces.length).fill(0);
12+
const rightMaxLevels = new Array(terraces.length).fill(0);
13+
14+
// Calculate the highest terrace level from the LEFT relative to the current terrace.
15+
[leftMaxLevels[0]] = terraces;
16+
for (let terraceIndex = 1; terraceIndex < terraces.length; terraceIndex += 1) {
17+
leftMaxLevels[terraceIndex] = Math.max(
18+
terraces[terraceIndex],
19+
leftMaxLevels[terraceIndex - 1],
20+
);
21+
}
7022

71-
while (leftIndex < rightIndex && terraces[leftIndex] <= leftMaxLevel) {
72-
waterAmount += leftMaxLevel - terraces[leftIndex];
73-
leftIndex += 1;
74-
}
75-
} else {
76-
// Move from right to left and collect water.
77-
rightIndex -= 1;
23+
// Calculate the highest terrace level from the RIGHT relative to the current terrace.
24+
rightMaxLevels[terraces.length - 1] = terraces[terraces.length - 1];
25+
for (let terraceIndex = terraces.length - 2; terraceIndex >= 0; terraceIndex -= 1) {
26+
rightMaxLevels[terraceIndex] = Math.max(
27+
terraces[terraceIndex],
28+
rightMaxLevels[terraceIndex + 1],
29+
);
30+
}
7831

79-
while (leftIndex < rightIndex && terraces[rightIndex] <= rightMaxLevel) {
80-
waterAmount += rightMaxLevel - terraces[rightIndex];
81-
rightIndex -= 1;
82-
}
32+
// Not let's go through all terraces one by one and calculate how much water
33+
// each terrace may accumulate based on previously calculated values.
34+
for (let terraceIndex = 0; terraceIndex < terraces.length; terraceIndex += 1) {
35+
// Pick the lowest from the left/right highest terraces.
36+
const currentTerraceBoundary = Math.min(
37+
leftMaxLevels[terraceIndex],
38+
rightMaxLevels[terraceIndex],
39+
);
40+
41+
if (currentTerraceBoundary > terraces[terraceIndex]) {
42+
waterAmount += currentTerraceBoundary - terraces[terraceIndex];
8343
}
8444
}
8545

0 commit comments

Comments
 (0)