The Maximum Volume of Trapped Rain Water in 3D
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
The usual "trapping rain water" problem becomes more interesting in 3D terrain because water can leak out in multiple directions. In the common algorithmic version, you are given a 2D grid of heights, and the goal is to compute how much water can be held above the cells after rainfall. The correct solution is not based on local neighbors alone; it depends on the lowest boundary that water can escape through.
Model the Terrain Correctly
Even though the title says 3D, the input is normally a 2D height map where each cell value represents elevation in the third dimension. Water is trapped on top of that surface, so the total trapped volume is the sum of water units above all cells.
For example, this terrain:
can trap water in some interior cells because the outer boundary is high enough to contain it.
The core insight is that the water level of a cell is determined by the minimum boundary height that can reach it from the outside. That is why a simple "compare to four neighbors" rule is not sufficient.
Use a Boundary-First Min-Heap Algorithm
The standard solution uses a min-heap seeded with all boundary cells. From there, you repeatedly expand inward from the currently lowest boundary. This works because the lowest boundary seen so far determines the maximum water level reachable without spilling.
The steps are:
- push all outer cells into a min-heap
- mark them as visited
- pop the lowest boundary cell
- inspect its four neighbors
- if a neighbor is lower, trap the height difference as water
- push the neighbor back with effective height
max(current_boundary, neighbor_height)
Here is a runnable Python implementation:
This prints 4, which is the trapped water volume for that sample.
Why the Heap Approach Works
The algorithm works for the same reason Dijkstra-style frontier expansion works in shortest path problems: you always process the next most restrictive boundary first. When a low wall is reached, it limits water level for any connected interior region.
If you tried to compute water using only local maxima around each cell, you would overestimate in cases where water can escape through a distant low boundary. The heap prevents that by building the reachable basin from the outside inward.
Time complexity is O(m * n * log(m * n)) because each cell enters the heap once, and each heap operation costs logarithmic time. Space complexity is O(m * n) for the heap and visited grid.
Test with Edge Cases
Before trusting the implementation, run small edge cases:
These checks catch two common mistakes:
- forgetting that grids smaller than
3 x 3cannot trap water - pushing cells with the wrong effective height back into the heap
For production code, unit tests should include irregular basins, multiple compartments, and flat boundaries.
When This Model Does Not Apply
This algorithm is for axis-aligned grid terrain. It does not directly solve continuous mesh simulation, fluid dynamics, or real-world hydrology with evaporation, flow speed, or porous materials. It is an algorithmic volume computation over a discrete height map.
That distinction matters. If the real problem is physical simulation, this heap-based method is a useful abstraction, not a physics engine.
Common Pitfalls
- Treating the problem like the 1D rainwater problem and comparing only local neighbors.
- Forgetting to seed the heap with every boundary cell before exploring inward.
- Pushing the neighbor's raw height instead of the effective boundary height
max(current, neighbor). - Failing to mark visited cells at the right time and processing cells more than once.
- Expecting this discrete algorithm to model full real-world fluid simulation behavior.
Summary
- The 3D rainwater volume problem is usually a 2D height map with water trapped above it.
- The correct solution is boundary-driven, not purely local.
- A min-heap over boundary cells gives the standard efficient algorithm.
- Each interior cell is evaluated against the lowest escape boundary discovered so far.
- Test edge cases carefully because small mistakes in heap updates lead to large overcounts.
Related reading
- The Most Efficient Way To Find Top K Frequent Words In A Big Word Sequence
- The most efficient way to implement an integer based power function powint, int
- the number of trailing zeros in a factorial of a given number - Ruby
- The relationship between Paxos family and data consistency
- The Sieve of Atkin
- This version of TensorFlow Probability requires TensorFlow version 2.3
- The sieve of Eratosthenes in F
- The simplest algorithm for poker hand evaluation

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.