|
5 | 5 | * @return {number}
|
6 | 6 | */
|
7 | 7 | export default function dpRainTerraces(terraces) {
|
8 |
| - let waterAmount = 0; |
| 8 | + // Obtain the maximum elevations to the left and right of each terrace (inclusive). |
| 9 | + const maxL = terraces.reduce((acc, val, idx) => [...acc, Math.max(val, (acc[idx - 1] || 0))], []); |
| 10 | + const maxR = terraces.reduceRight((acc, val) => [Math.max(val, (acc[0] || 0)), ...acc], []); |
9 | 11 |
|
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 |
| - } |
22 |
| - |
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 |
| - } |
31 |
| - |
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]; |
43 |
| - } |
44 |
| - } |
45 |
| - |
46 |
| - return waterAmount; |
| 12 | + // Convert maximum values to amount of water at current index and sum water values. |
| 13 | + const trap = terraces.map((val, idx) => Math.max(0, Math.min(maxL[idx], maxR[idx]) - val)); |
| 14 | + return trap.reduce((acc, val) => acc + val); |
47 | 15 | }
|
0 commit comments