diff --git a/src/algorithms/uncategorized/rain-terraces/dpRainTerraces.js b/src/algorithms/uncategorized/rain-terraces/dpRainTerraces.js index 1c48cbd8..9c4f9ad5 100644 --- a/src/algorithms/uncategorized/rain-terraces/dpRainTerraces.js +++ b/src/algorithms/uncategorized/rain-terraces/dpRainTerraces.js @@ -5,43 +5,11 @@ * @return {number} */ export default function dpRainTerraces(terraces) { - let waterAmount = 0; + // Obtain the maximum elevations to the left and right of each terrace (inclusive). + const maxL = terraces.reduce((acc, val, idx) => [...acc, Math.max(val, (acc[idx - 1] || 0))], []); + const maxR = terraces.reduceRight((acc, val) => [Math.max(val, (acc[0] || 0)), ...acc], []); - // Init arrays that will keep the list of left and right maximum levels for specific positions. - const leftMaxLevels = new Array(terraces.length).fill(0); - const rightMaxLevels = new Array(terraces.length).fill(0); - - // Calculate the highest terrace level from the LEFT relative to the current terrace. - [leftMaxLevels[0]] = terraces; - for (let terraceIndex = 1; terraceIndex < terraces.length; terraceIndex += 1) { - leftMaxLevels[terraceIndex] = Math.max( - terraces[terraceIndex], - leftMaxLevels[terraceIndex - 1], - ); - } - - // Calculate the highest terrace level from the RIGHT relative to the current terrace. - rightMaxLevels[terraces.length - 1] = terraces[terraces.length - 1]; - for (let terraceIndex = terraces.length - 2; terraceIndex >= 0; terraceIndex -= 1) { - rightMaxLevels[terraceIndex] = Math.max( - terraces[terraceIndex], - rightMaxLevels[terraceIndex + 1], - ); - } - - // Not let's go through all terraces one by one and calculate how much water - // each terrace may accumulate based on previously calculated values. - for (let terraceIndex = 0; terraceIndex < terraces.length; terraceIndex += 1) { - // Pick the lowest from the left/right highest terraces. - const currentTerraceBoundary = Math.min( - leftMaxLevels[terraceIndex], - rightMaxLevels[terraceIndex], - ); - - if (currentTerraceBoundary > terraces[terraceIndex]) { - waterAmount += currentTerraceBoundary - terraces[terraceIndex]; - } - } - - return waterAmount; + // Convert maximum values to amount of water at current index and sum water values. + const trap = terraces.map((val, idx) => Math.max(0, Math.min(maxL[idx], maxR[idx]) - val)); + return trap.reduce((acc, val) => acc + val); }