Trapping Rain Water Using Stack in DSA Python - Time & Space Complexity
We want to understand how the time taken grows when we use a stack to solve the trapping rain water problem.
How does the number of steps change as the height list gets bigger?
Analyze the time complexity of the following code snippet.
def trap(height):
stack = []
water = 0
for i, h in enumerate(height):
while stack and height[stack[-1]] < h:
top = stack.pop()
if not stack:
break
distance = i - stack[-1] - 1
bounded_height = min(h, height[stack[-1]]) - height[top]
water += distance * bounded_height
stack.append(i)
return water
This code calculates how much water can be trapped after raining using a stack to track bars.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop goes through each bar once, and the while-loop pops bars from the stack when the current bar is taller.
- How many times: Each bar is pushed and popped at most once, so the total number of stack operations is at most 2n for n bars.
As the number of bars increases, the total steps grow roughly in a straight line with the number of bars.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 stack operations |
| 100 | About 200 stack operations |
| 1000 | About 2000 stack operations |
Pattern observation: The operations grow linearly, doubling the input roughly doubles the work.
Time Complexity: O(n)
This means the time taken grows directly in proportion to the number of bars in the input.
[X] Wrong: "The nested while-loop makes this algorithm O(n²) because it looks like a loop inside a loop."
[OK] Correct: Each bar is pushed and popped only once, so the total number of operations is still proportional to n, not n squared.
Understanding this stack approach shows you can use data structures smartly to solve problems efficiently, a skill valued in many coding challenges.
"What if we used a simple nested loop instead of a stack? How would the time complexity change?"
Practice
Trapping Rain Water Using Stack algorithm?Solution
Step 1: Understand the role of the stack
The stack stores indices of bars that are waiting to find a right boundary to trap water.Step 2: Why not other options?
The stack does not store water amount or sort bars; it helps find boundaries for trapped water.Final Answer:
To keep track of bars that are not yet processed for water trapping -> Option CQuick Check:
Stack tracks bars for trapping water = B [OK]
- Thinking stack stores water amount
- Assuming stack sorts the bars
- Believing stack reverses the array
Solution
Step 1: Identify correct stack initialization
In Python, a stack is commonly represented by a list, sostack = []initializes an empty stack.Step 2: Why other options are wrong
{}is a dictionary,Noneis no value, and0is an integer, none suitable for stack operations.Final Answer:
stack = [] -> Option DQuick Check:
Empty list for stack = A [OK]
- Using {} which creates a dictionary
- Assigning None instead of list
- Using integer 0 as stack
def trap(height):
stack = []
water = 0
for i, h in enumerate(height):
while stack and height[stack[-1]] < h:
top = stack.pop()
if not stack:
break
distance = i - stack[-1] - 1
bounded_height = min(height[stack[-1]], h) - height[top]
water += distance * bounded_height
stack.append(i)
return water
print(trap([0,1,0,2,1,0,1,3,2,1,2,1]))Solution
Step 1: Trace the algorithm with given heights
The code calculates trapped water for heights [0,1,0,2,1,0,1,3,2,1,2,1]. The total trapped water is 6 units.Step 2: Confirm calculation matches known example
This is a classic example where trapped water is 6, matching the output of the code.Final Answer:
6 -> Option AQuick Check:
Trapped water = 6 [OK]
- Miscounting trapped water units
- Ignoring stack pop conditions
- Wrong distance or bounded height calculation
def trap(height):
stack = []
water = 0
for i, h in enumerate(height):
while stack and height[stack[-1]] <= h:
top = stack.pop()
if not stack:
break
distance = i - stack[-1] - 1
bounded_height = min(height[stack[-1]], h) - height[top]
water += distance * bounded_height
stack.append(i)
return water
print(trap([4,2,0,3,2,5]))Solution
Step 1: Check the while loop condition
The conditionheight[stack[-1]] <= hcauses popping even when heights are equal, which is incorrect for trapping water calculation.Step 2: Correct condition and reason
It should beheight[stack[-1]] < hto pop only when current height is strictly greater, ensuring correct water trapping.Final Answer:
The condition should be < instead of <= -> Option BQuick Check:
Use < not <= in while condition [OK]
- Using <= causes wrong popping
- Confusing stack with queue
- Incorrect distance formula
- Initializing water to 1 instead of 0
[3, 0, 2, 0, 4], what is the total trapped rain water calculated using the stack method? Explain how the stack helps in this calculation.Solution
Step 1: Calculate trapped water step-by-step
Heights: [3,0,2,0,4]. Water trapped at position 1 is 3 units, at position 2 is 0 units, at position 3 is 1 unit. Total trapped water = 4 units.Step 2: Explain stack role in calculation
The stack stores indices of bars. When a higher bar is found, it pops lower bars and calculates trapped water using distance and bounded height between bars.Final Answer:
4 -> Option AQuick Check:
Stack helps find boundaries; trapped water = 4 [OK]
- Adding trapped water incorrectly
- Ignoring zero height bars
- Not using stack to find boundaries
Ready to prove it?
Pass the test and this pattern moves unknown
