Trapping Rain Water Problem in DSA Python - Time & Space Complexity
We want to understand how the time taken to solve the Trapping Rain Water problem changes as the input size grows.
Specifically, how the number of operations depends on the number of bars in the elevation map.
Analyze the time complexity of the following code snippet.
def trap(height):
n = len(height)
left, right = 0, n - 1
left_max, right_max = 0, 0
water = 0
while left <= right:
if height[left] < height[right]:
if height[left] > left_max:
left_max = height[left]
else:
water += left_max - height[left]
left += 1
else:
if height[right] > right_max:
right_max = height[right]
else:
water += right_max - height[right]
right -= 1
return water
This code calculates how much water can be trapped between bars represented by the list height.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves two pointers across the array.
- How many times: Each element is visited at most once by either the left or right pointer, so total visits are proportional to the array length.
As the number of bars increases, the loop runs once per bar, so operations grow linearly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: Doubling the input size roughly doubles the number of operations.
Time Complexity: O(n)
This means the time to compute trapped water grows directly in proportion to the number of bars.
[X] Wrong: "Because there are nested if-else statements, the time complexity must be quadratic O(n²)."
[OK] Correct: The if-else statements are inside a single loop that moves pointers only once through the array, so the total steps are still linear, not multiplied.
Understanding this linear time solution shows you can optimize problems by clever pointer use instead of brute force, a skill highly valued in interviews.
"What if we used two nested loops to check water trapped at each bar? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem context
The problem gives an array representing heights of bars and asks how much water can be trapped between them after rain.Step 2: Identify the goal
The goal is to calculate the total trapped water volume between bars, not just the tallest bar or sum of heights.Final Answer:
The total amount of water trapped between bars -> Option CQuick Check:
Trapped water = total water held between bars [OK]
- Confusing trapped water with tallest bar height
- Summing bar heights instead of water trapped
- Ignoring spaces between bars where water collects
Solution
Step 1: Understand pointer initialization
Two pointers start at the ends: left at 0, right at last index (length - 1).Step 2: Check each option
left, right = 0, len(height) - 1 correctly sets left=0 and right=len(height)-1. Others have invalid indices.Final Answer:
left, right = 0, len(height) - 1 -> Option AQuick Check:
Start pointers at array ends [OK]
- Setting right pointer to len(height) (out of range)
- Starting left pointer at 1 instead of 0
- Using negative indices incorrectly
def trap(height):
left, right = 0, len(height) - 1
left_max = right_max = 0
water = 0
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
water += left_max - height[left]
left += 1
else:
if height[right] >= right_max:
right_max = height[right]
else:
water += right_max - height[right]
right -= 1
return water
print(trap([0,1,0,2,1,0,1,3,2,1,2,1]))Solution
Step 1: Trace pointers and water accumulation
Using two pointers, water trapped is calculated by comparing left and right heights and updating max heights.Step 2: Calculate trapped water for given input
For input [0,1,0,2,1,0,1,3,2,1,2,1], total trapped water is 6 units.Final Answer:
6 -> Option BQuick Check:
Standard example result = 6 [OK]
- Miscounting trapped water units
- Not updating max heights correctly
- Confusing left and right pointer moves
def trap(height):
left, right = 0, len(height) - 1
left_max = right_max = 0
water = 0
while left <= right:
if height[left] < height[right]:
if height[left] > left_max:
left_max = height[left]
else:
water += left_max - height[left]
left += 1
else:
if height[right] > right_max:
right_max = height[right]
else:
water += right_max - height[right]
right -= 1
return water
Solution
Step 1: Analyze the loop condition
The loop uses 'left <= right', which causes pointers to cross and double count or error.Step 2: Correct loop condition
Changing to 'left < right' prevents overlap and ensures correct water calculation.Final Answer:
The while loop condition should be 'left < right' instead of 'left <= right' -> Option AQuick Check:
Loop ends before pointers cross [OK]
- Using <= causes double counting
- Not updating max heights correctly
- Incorrect pointer initialization
[4,2,0,3,2,5], what is the total trapped rain water? Use the two-pointer approach to solve.Solution
Step 1: Initialize pointers and max heights
left=0, right=5, left_max=0, right_max=0, water=0.Step 2: Move pointers and calculate trapped water
Walk through: - left=0 (4), right=5 (5), left < right - height[left]Final Answer:
9 -> Option DQuick Check:
Sum trapped water units = 9 [OK]
- Miscounting trapped water at zero height bars
- Not updating left_max and right_max correctly
- Stopping loop too early or late
Ready to prove it?
Pass the test and this pattern moves unknown
