Trapping Rain Water — Solution in Python, Java & C++
Trapping Rain Water solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A hard problem.
Trapping Rain Water is a hard coding problem on arrays, dynamic programming and two pointers, asked in Airbnb, Twitter, Databricks and PhonePe interviews.
- Difficulty: Hard
- Topics: Arrays, Dynamic Programming, Two Pointers, Stack
- Asked at: Airbnb, Twitter, Databricks, PhonePe, Sprinklr, Ola, HCL, Palantir
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
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.
Example 1
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Example 2
Input: height = [4,2,0,3,2,5]
Output: 9
Constraints
1 <= height.length <= 300 <= height[i] <= 100
Hints for Trapping Rain Water
Hint 1
Water above position i is min(maxLeft, maxRight) - height[i].
Hint 2
Two pointers moving inward, tracking the running max from each side, gives O(n)/O(1).
How to solve Trapping Rain Water
Water above a bar is limited by the shorter of the tallest wall to its left and the tallest to its right. Two pointers let you resolve that without precomputing both arrays: whichever side is currently shorter is the binding constraint, so that side can be settled and advanced immediately.
Approach
- Put
lat the start andrat the end, trackingleftMaxandrightMax. - If
height[l] < height[r], the left side is the limiting one. - In that case: if
height[l]is at leastleftMax, it becomes the newleftMax; otherwise it trapsleftMax - height[l]. Advancel. - Otherwise do the mirror image on the right and move
rinward. - Continue until the pointers meet.
Why it works
When height[l] < height[r], there is guaranteed to be some wall on the right at least as tall as height[r], so the water above position l is decided entirely by leftMax — the right side cannot be the smaller of the two. That makes the left position safe to finalise without knowing the actual right maximum, which is what removes the need for a precomputed suffix array. The mirror argument covers the other branch, and each step retires one position.
Complexity
- Time —
O(n) - Space —
O(1)
Pitfalls
- Advance the pointer on the shorter side; moving the taller one breaks the guarantee the argument depends on.
- Update the running maximum or add water, never both for the same bar.
- Water is
max - height, which is0at a new maximum — no negative contributions. - Compare
height[l]withheight[r], notleftMaxwithrightMax, when deciding which side to move.
Reference solution
Python
from typing import List
def trap(height: List[int]) -> int:
l, r = 0, len(height) - 1
lm = rm = water = 0
while l < r:
if height[l] < height[r]:
lm = max(lm, height[l])
water += lm - height[l]
l += 1
else:
rm = max(rm, height[r])
water += rm - height[r]
r -= 1
return waterJava
public static int trap(int[] height) {
int l = 0, r = height.length - 1, leftMax = 0, rightMax = 0, total = 0;
while (l < r) {
if (height[l] < height[r]) {
if (height[l] >= leftMax) leftMax = height[l];
else total += leftMax - height[l];
l++;
} else {
if (height[r] >= rightMax) rightMax = height[r];
else total += rightMax - height[r];
r--;
}
}
return total;
}C++
int trap(vector<int>& height) {
int l = 0, r = (int) height.size() - 1, leftMax = 0, rightMax = 0, total = 0;
while (l < r) {
if (height[l] < height[r]) {
if (height[l] >= leftMax) leftMax = height[l];
else total += leftMax - height[l];
l++;
} else {
if (height[r] >= rightMax) rightMax = height[r];
else total += rightMax - height[r];
r--;
}
}
return total;
}JavaScript
var trap = function(height) {
let l = 0, r = height.length - 1;
let lm = 0, rm = 0, water = 0;
while (l < r) {
if (height[l] < height[r]) {
lm = Math.max(lm, height[l]);
water += lm - height[l];
l++;
} else {
rm = Math.max(rm, height[r]);
water += rm - height[r];
r--;
}
}
return water;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 1199 arrays problems · the whole catalogue
Learn the technique: Arrays · Dynamic Programming