42. Trapping Rain Water
hardAsked at AMDCalculate how much water can be trapped between elevation bars. AMD uses this to test two-pointer reasoning under asymmetric constraints — the same left/right boundary propagation appears in memory range overlap analysis, voltage droop modeling, and signal amplitude clipping detection in hardware bring-up tooling.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in AMD loops.
- Glassdoor (2026-Q1)— AMD SWE candidates report Trapping Rain Water appearing in hard coding rounds, valued for its two-pointer space optimization.
- Blind (2025-11)— AMD interview threads flag this as a hard problem that AMD uses specifically to test two-pointer depth and space-complexity awareness.
Problem
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.
Constraints
n == height.length1 <= n <= 2 * 10^40 <= height[i] <= 10^5
Examples
Example 1
height = [0,1,0,2,1,0,1,3,2,1,2,1]6Explanation: The elevation map traps 6 units of water.
Example 2
height = [4,2,0,3,2,5]9Explanation: 9 units trapped between the bars.
Approaches
1. Precompute left-max and right-max arrays
For each index, water trapped = min(maxLeft[i], maxRight[i]) - height[i]. Precompute both max arrays in two linear passes, then compute the total.
- Time
- O(n)
- Space
- O(n)
function trap(height) {
const n = height.length;
const maxLeft = new Array(n).fill(0);
const maxRight = new Array(n).fill(0);
for (let i = 1; i < n; i++) maxLeft[i] = Math.max(maxLeft[i-1], height[i-1]);
for (let i = n-2; i >= 0; i--) maxRight[i] = Math.max(maxRight[i+1], height[i+1]);
let water = 0;
for (let i = 0; i < n; i++) {
const level = Math.min(maxLeft[i], maxRight[i]);
if (level > height[i]) water += level - height[i];
}
return water;
}Tradeoff: O(n) time, O(n) space. Clear and easy to reason about. The three-pass structure makes it easy to verify correctness.
2. Two Pointers (O(1) space)
Maintain left and right pointers and running left/right maximums. The side with the smaller max can be computed confidently — water at that position is maxSide - height[side]. Advance the pointer with the smaller max.
- Time
- O(n)
- Space
- O(1)
function trap(height) {
let left = 0, right = height.length - 1;
let leftMax = 0, rightMax = 0;
let water = 0;
while (left < right) {
if (height[left] <= height[right]) {
if (height[left] >= leftMax) leftMax = height[left];
else water += leftMax - height[left];
left++;
} else {
if (height[right] >= rightMax) rightMax = height[right];
else water += rightMax - height[right];
right--;
}
}
return water;
}Tradeoff: O(1) space — the best approach. The key insight: if leftMax < rightMax, the water at the left pointer is bounded by leftMax regardless of what's between left and right (because we know there's something >= leftMax on the right). AMD expects this version.
AMD-specific tips
AMD values the O(1) space two-pointer version specifically because it demonstrates the ability to reason under asymmetric information: 'I know the right side is at least rightMax — so whatever is between left and right doesn't matter for the left pointer's water calculation.' This type of argument appears in hardware boundary analysis: if you know one side of a voltage rail can sustain a certain level, you can compute droops on the other side without full system knowledge. State the invariant before coding it.
Common mistakes
- Confusing which pointer to advance — advance the one with the smaller max (not height), because that side's water is deterministic.
- Using height[left] < height[right] for the condition instead of <= — either works for correctness, but be consistent.
- Not initializing leftMax and rightMax to 0 — they track the maximum height seen so far from each side.
- Computing water as max-height without checking that max > height — negative water is nonsensical; use Math.max(0, level - height[i]) or an explicit if.
Follow-up questions
An interviewer at AMD may pivot to one of these next:
- Container With Most Water (LC 11) — two-pointer to maximize the rectangle area, not trapped water.
- Largest Rectangle in Histogram (LC 84) — extends the boundary-sweep technique.
- How would you model voltage droop across a power delivery network using this pattern?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why can we advance the smaller-max pointer safely?
If leftMax <= rightMax, then the water at left is capped by leftMax — even if the right side has a very high bar somewhere, leftMax is the binding constraint. We don't need to know what's in between. The right side guarantees at least rightMax >= leftMax, so water won't spill right.
What if all heights are equal?
No water is trapped — every position's water level equals its height, resulting in 0 contribution. The algorithm handles this: leftMax == height[left] so no water is added, and left increments.
Practice these live with InterviewChamp.AI
Drill Trapping Rain Water and other AMD interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →