Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Lines changed: 31 additions & 71 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /