Given height, an array where height[i] is the height of a bar of width 1, compute how much rain water can be trapped between the bars after it rains.
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1] Output: 6 The dips between the bars trap 6 units of water in total.
Input: height = [4,2,0,3,2,5] Output: 9 Water pools between the tall end bars for a total of 9 units.
- 1 <= height.length <= 2 * 10^4 - 0 <= height[i] <= 10^5
Water sitting above bar i is bounded by the shorter of the tallest bar to its left and the tallest bar to its right, minus its own height: min(leftMax, rightMax) - height[i]. Computing those maxima naively is O(n) per bar; a two-pointer sweep gets the whole answer in O(n) time and O(1) space by always advancing the shorter side.
“Do the bars have width?”
Yes — each has width 1, so trapped water above bar i is a column of height min(leftMax, rightMax) - height[i].
“Can water be negative?”
No — if a bar is at least as tall as its bounding walls, it traps 0.
The water on top of each bar is min(tallest-to-the-left, tallest-to-the-right) minus its own height.
I use two pointers and track the running max on each side.
Whichever side is shorter is the binding wall, so I add its water and move it inward — O(1) space.
Worked example — height = [0,1,0,2,1,0,1,3,2,1,2,1]
water traps in the dips between taller bars, totaling 6 units answer: 6
Bar i holds min(leftMax, rightMax) - height[i] of water — the taller wall doesn't matter, the shorter one caps the level.
If height[l] < height[r], the left wall is binding for bar l (the right can only be taller), so leftMax - height[l] is exact. Move l. Symmetric for the right.
Running leftMax/rightMax replace the two prefix/suffix-max arrays, so the sweep needs only a few variables.
| Scan both sides per bar | Two pointers | |
|---|---|---|
| Idea | For each bar, find left and right maxima by scanning | Advance the shorter side with running maxima |
| Time | O(n^2) | O(n) |
| Space | O(1) | O(1) |
(A middle-ground stores prefix/suffix maxima in O(n) space for O(n) time; the two-pointer version removes even that.) Full code is in the Approaches selector below.
Key takeaway
Water above each bar is min(leftMax, rightMax) - height[i]. Two pointers with running maxima always advance the shorter side — whose max is the exact binding wall — accumulating the trapped water in O(n) time and O(1) space.
l, r = 0, n-1; leftMax = rightMax = water = 0
while l < r:
if height[l] < height[r]: leftMax = max(leftMax, height[l]); water += leftMax - height[l]; l += 1
else: rightMax = max(rightMax, height[r]); water += rightMax - height[r]; r -= 1
return water