How to Explain Trapping Rain Water in a Coding Interview (Step-by-Step)
Trapping Rain Water is one of the most iconic Hard problems in coding interviews. There are three valid approaches — brute force, prefix arrays, and two pointers — and knowing all three, plus how they relate to each other, is what makes a candidate stand out.
In this post, you’ll learn exactly how to walk an interviewer through this problem: the core formula, why the two-pointer approach works, and which edge cases to call out proactively.
Problem Statement
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.
Examples
Output: 6
Output: 9
Constraints
n == height.length1 <= n <= 2 * 10⁴0 <= height[i] <= 10⁵
What Is the Problem?
“I have an elevation map as an array of bar heights. After rain, water collects in the valleys between taller bars. I need to compute the total volume of water trapped — treating each index as a column of width 1.”
The Core Formula — Water at Each Cell
For any position i, the water it can hold equals the minimum of the tallest bar to its left and the tallest bar to its right, minus its own height.
If that value is negative — meaning the bar itself is taller than one of the surrounding walls — no water sits on top of it.
Explain this formula before touching any approach. Once the interviewer understands it, every approach is just a different way to compute max_left and max_right efficiently.
Step 1: Walk Through All Three Approaches
For each cell, scan left and right to find max walls
Time: O(n²)
Space: O(1)
Precompute max_left and max_right arrays
Time: O(n)
Space: O(n)
Compute on-the-fly — no extra arrays needed
Time: O(n)
Space: O(1)
Approach 2 — Prefix Arrays (Explain First, Code Second)
“I precompute two arrays —max_left[i]is the tallest bar from index 0 to i, andmax_right[i]is the tallest bar from i to n-1. Then for each cell I apply the formula. This is O(n) time and O(n) space — a clean stepping stone to the optimal solution.”
def trap(height: List[int]) -> int:
n = len(height)
max_left = [0] * n
max_right = [0] * n
# Fill max_left — running max from left to right
max_left[0] = height[0]
for i in range(1, n):
max_left[i] = max(max_left[i-1], height[i])
# Fill max_right — running max from right to left
max_right[n-1] = height[n-1]
for i in range(n-2, -1, -1):
max_right[i] = max(max_right[i+1], height[i])
# Apply formula at each cell
total = 0
for i in range(n):
total += max(0, min(max_left[i], max_right[i]) - height[i])
return total
Approach 3 — Two Pointers (Optimal, Lead With This)
We don’t need the full max_left and max_right arrays. At any position, water is determined by the smaller of the two max walls. So whichever side has the smaller max wall, we can safely process that side — because we already know the other side is at least as tall.
Process the side with the smaller max. Move that pointer inward. Repeat.
“Ifmax_left <= max_right, the left side is the bottleneck. Water at the left pointer ismax_left - height[left]. We add it and move left forward. Otherwise we do the same for the right pointer. We never need to look the other way.”
The Code — Two Pointer Solution
class Solution:
def trap(self, height: List[int]) -> int:
left, right = 0, len(height) - 1
max_left, max_right = 0, 0 # Running max walls on each side
total = 0
while left < right:
if height[left] <= height[right]:
# Left side is the bottleneck — process it
if height[left] >= max_left:
max_left = height[left] # New max wall — no water here
else:
total += max_left - height[left] # Water above this cell
left += 1
else:
# Right side is the bottleneck — process it
if height[right] >= max_right:
max_right = height[right] # New max wall — no water here
else:
total += max_right - height[right] # Water above this cell
right -= 1
return total
Key thing to point out: max_left and max_right are single integers — not arrays. That’s what drops space from O(n) to O(1).
Visual Walkthrough
Using height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1] — total water = 6:
Water per cell — applying the formula at each index:
| Index | height[i] | max_left | max_right | min(L,R) | water |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 3 | 0 | 0 |
| 1 | 1 | 1 | 3 | 1 | 0 |
| 2 | 0 | 1 | 3 | 1 | 1 |
| 3 | 2 | 2 | 3 | 2 | 0 |
| 4 | 1 | 2 | 3 | 2 | 1 |
| 5 | 0 | 2 | 3 | 2 | 2 |
| 6 | 1 | 2 | 3 | 2 | 1 |
| 7 | 3 | 3 | 3 | 3 | 0 |
| 8 | 2 | 3 | 2 | 2 | 0 |
| 9 | 1 | 3 | 2 | 2 | 1 |
| 10 | 2 | 3 | 2 | 2 | 0 |
| 11 | 1 | 3 | 1 | 1 | 0 |
Step 5: Highlight Edge Cases
“e.g.[1, 2, 3, 4]— water is always zero because there’s no wall on one side to trap it.min(max_left, max_right) - height[i]will always be ≤ 0. Themax(0, ...)handles this correctly.”
“With only 1 or 2 bars, no water can be trapped — there’s no valley. The two-pointer loop condition left < right is immediately false for n=1. For n=2 it runs once but both bars are walls so water = 0.”
“If all heights are 0, there are no walls at all. Every cell computes min(0, 0) - 0 = 0. Total water = 0. Correct.”
“e.g.[1, 0, 1]— the middle bar traps 1 unit.min(1, 1) - 0 = 1. The two-pointer handles this in one step: left=0, right=2, process left (height 1 = max_left, no water), move left to 1. Now height[1]=0 < max_left=1, add 1 unit. Move left to 2. Left = right, stop.”
Step 6: State Time and Space Complexity
| Approach | Time | Space |
|---|---|---|
| Brute Force | O(n²) | O(1) |
| Prefix Arrays | O(n) | O(n) |
| Two Pointers ✓ | O(n) | O(1) |
“The two-pointer solution is strictly better than the prefix array approach — same O(n) time but O(1) space instead of O(n). Each element is processed exactly once as the pointers converge from both ends.”
Interview Checklist for Trapping Rain Water
- Restate — “total water trapped = sum of water above each bar”
- State the formula —
water[i] = max(0, min(max_left, max_right) - height[i]) - Present all three approaches — brute force, prefix arrays, two pointers
- Explain prefix arrays first — it’s the clearest path to understanding
- Explain the two-pointer insight — process the side with the smaller max wall
- Clarify that
max_leftandmax_rightare single integers, not arrays - Handle monotonic array — no water possible, formula gives 0
- Handle single/two element — loop doesn’t run or yields 0
- State O(n²) → O(n)/O(n) → O(n)/O(1) progression clearly
- Ask before coding, don’t just dive in
Related Problems to Practice
If you can solve Trapping Rain Water cleanly, try these next:
