Code Logo

Trapping Rain Water

Published at23 Jul 2026
Hard 0 views
Like0

You are given an array of non-negative integers representing elevation heights. After it rains, water gets trapped between the elevations. Compute the total amount of trapped water.

A monotonic decreasing stack efficiently solves this. Iterate through the heights. When the current height is greater than the height at the top of the stack, pop the top (the valley). The water trapped above this valley is determined by the min of the left wall (new top of stack) and right wall (current height), minus the valley height, multiplied by the distance between the walls.

This approach processes each bar once and calculates trapped water volume whenever a right wall is found for a valley.

The monotonic decreasing stack approach processes each bar exactly once. When a taller bar arrives, it forms a right wall for the valley at the top of the stack. The left wall is the new top of stack after popping the valley. The water trapped above that valley is bounded by the shorter of the two walls minus the valley height, spread across the distance between the walls.

This approach might seem complex at first, but it directly models the physics of water: water collects in valleys, and each valley is bounded by the nearest taller wall on the left and right. The stack efficiently discovers these relationships.

Alternative approaches include two-pointer and prefix/suffix max arrays, both also O(n). The stack approach is the most general and extends naturally to other problems.

Edge cases include flat terrain (no water), single bar (no water), and descending terrain (no water).

The stack approach directly models the physical process of water filling valleys. Each time a taller bar is encountered, it reveals a valley that can hold water between the current bar and the previous taller bar in the stack. The amount of water is computed layer by layer, not column by column.

A helpful mental model: the stack holds indices of bars that could potentially serve as left walls. When a taller bar arrives, it becomes a right wall, and water is collected above the valleys formed by the shorter bars between the walls. The process repeats for each layer of valleys.

Understanding this problem deeply will help with other geometric computation problems using stacks.

Example Input & Output

Example 1
Input
[4,2,0,3,2,5]
Output
9
Explanation

Water trapped: 2 units at index 2 (between 4 and 3), then more between 3 and 5.

Example 2
Input
[0,1,0,2,1,0,1,3,2,1,2,1]
Output
6
Explanation

Water trapped in 4 valleys between elevations. Visualize as a mountain profile.

Example 3
Input
[1,0,1]
Output
1
Explanation

Single unit of water trapped at index 1 between two walls of height 1.

Algorithm Flow

Recommendation Algorithm Flow for Trapping Rain Water
Recommendation Algorithm Flow for Trapping Rain Water

Solution Approach

Create a stack to store indices. Iterate through heights. While the stack is not empty and the current height is greater than the height at the top of the stack, pop the top index as the valley. If the stack is empty after popping, no left wall exists, so no water can be trapped. Otherwise, calculate the distance between the current index and the new top of stack minus 1, and the bounded height as the min of the current height and the height at the new top minus the valley height. Add the product to the total water.

function solution(height) {
  var stack = [];
  var water = 0;
  for (var i = 0; i < height.length; i++) {
    while (stack.length && height[i] > height[stack[stack.length - 1]]) {
      var valley = stack.pop();
      if (!stack.length) break;
      var left = stack[stack.length - 1];
      var distance = i - left - 1;
      var boundedHeight = Math.min(height[i], height[left]) - height[valley];
      water += distance * boundedHeight;
    }
    stack.push(i);
  }
  return water;
}

Time complexity is O(n). Space complexity is O(n).

Best Answers

java
import java.util.*;
class Solution {
    public int solution(int[] height) {
        Stack<Integer> stack = new Stack<>();
        int water = 0;
        for (int i = 0; i < height.length; i++) {
            while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
                int valley = stack.pop();
                if (stack.isEmpty()) break;
                int left = stack.peek();
                int distance = i - left - 1;
                int boundedHeight = Math.min(height[i], height[left]) - height[valley];
                water += distance * boundedHeight;
            }
            stack.push(i);
        }
        return water;
    }
}