diff --git a/javascript/42-Trapping-Rain-Water.js b/javascript/42-Trapping-Rain-Water.js new file mode 100644 index 000000000..389b6a97a --- /dev/null +++ b/javascript/42-Trapping-Rain-Water.js @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////////// +// Space: O(n) Time: O(1) One iteration. +////////////////////////////////////////////////////////////////////////////// + +/** + * @param {!Array} heights + * @return {number} + */ +function trap(heights) { + + let l = 0; + let r = heights.length - 1; + let lMax = 0; + let rMax = 0; + let total = 0; + + while (l < r) { + if (heights[l] < heights[r]) { + if (heights[l] >= lMax) { + lMax = heights[l]; + } else { + total += lMax - heights[l]; + } + ++l; + } else { + if (heights[r] >= rMax) { + rMax = heights[r]; + } else { + total += rMax - heights[r]; + } + --r; + } + } + + return total; +} + +////////////////////////////////////////////////////////////////////////////// +// Space: O(n) Time: O(n) Two iterations (one main loop and one stack). +////////////////////////////////////////////////////////////////////////////// + +/** + * @param {!Array} heights + * @return {number} + */ +function trap(heights) { + + const stack = []; + let total = 0; + + for (let i = 0; i < heights.length; ++i) { + while (stack.length && heights[i] > heights[top(stack)]) { + + const j = stack.pop(); + + if (!stack.length) { + break; + } + + const k = top(stack); + const spread = i - k - 1; + const height = Math.min(heights[i], heights[k]) - heights[j]; + total += spread * height; + } + + stack.push(i); + } + + return total; +} + +/** + * @param {!Array<*>} stack + * @return {*} + */ +function top(stack) { + return stack[stack.length - 1]; +} + +////////////////////////////////////////////////////////////////////////////// +// Space: O(n) Time: O(n) Three iterations (two main loop and one stack). +////////////////////////////////////////////////////////////////////////////// + +/** + * @param {!Array} heights + * @return {number} + */ +function trap(heights) { + + let valley = []; + let barrier = 0; + let trapped = 0; + + for (const height of heights) { + if (height >= barrier) { + while (valley.length) { + trapped += barrier - valley.pop(); + } + barrier = height; + } else { + valley.push(height); + } + } + + valley.reverse(); + valley.push(barrier); + heights = valley; + valley = []; + barrier = 0; + + for (const height of heights) { + if (height >= barrier) { + while (valley.length) { + trapped += barrier - valley.pop(); + } + barrier = height; + } else { + valley.push(height); + } + } + + return trapped; +} \ No newline at end of file