Trapping Rain Water
Explanation & Solution
Description
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Output: 6
Explanation: The elevation map [0,1,0,2,1,0,1,3,2,1,2,1] traps 6 units of rain water. Water fills the valleys between the bars: 1 unit between indices 1-3, 4 units between indices 3-7, and 1 unit between indices 8-10.
Constraints
n == height.length1 <= n <= 2 * 10⁴0 <= height[i] <= 10⁵
Approach
Two Pointers pattern
1. Initialize Two Pointers and Tracking Variables
- Set
left = 0(start of array) andright = height.length - 1(end of array) - Set
leftMax = 0to track the tallest bar seen from the left - Set
rightMax = 0to track the tallest bar seen from the right - Set
water = 0to accumulate the total trapped water
2. Compare Heights at Both Pointers
- At each step, compare
height[left]withheight[right] - Process the side with the smaller height, because the water level at that position is determined by its own side's maximum (the other side is guaranteed to be at least as tall)
3. Process the Left Pointer
- If
height[left] < height[right], process the left side - If
height[left] >= leftMax, updateleftMax— this bar is a new boundary, no water is trapped here - Otherwise,
leftMax - height[left]units of water are trapped above this bar — add that towater - Move
left++
4. Process the Right Pointer
- If
height[right] <= height[left], process the right side - If
height[right] >= rightMax, updaterightMax— this bar is a new boundary, no water is trapped here - Otherwise,
rightMax - height[right]units of water are trapped above this bar — add that towater - Move
right--
5. Repeat Until Pointers Meet
- Continue the loop while
left < right - Each iteration processes exactly one position, giving O(n) time complexity
- Only a constant number of variables are used, giving O(1) space complexity
6. Return the Result
- After the loop,
watercontains the total amount of trapped rain water - Return
water
Key Insight
The water trapped at any position depends on the minimum of the tallest bar to its left and the tallest bar to its right, minus its own height. By processing from both ends inward and always choosing the smaller side, we can guarantee that the max on the opposite side is at least as large — so we only need to track the max on the side we are processing. This eliminates the need for precomputed arrays and achieves O(1) space.
Visualization
Press ▶ or use ← → to step through