Trapping Rain Water Problem in DSA Typescript - Time & Space Complexity
We want to understand how the time needed 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.
function trap(height: number[]): number {
let left = 0, right = height.length - 1;
let leftMax = 0, rightMax = 0;
let water = 0;
while (left < right) {
if (height[left] < height[right]) {
leftMax = Math.max(leftMax, height[left]);
water += leftMax - height[left];
left++;
} else {
rightMax = Math.max(rightMax, height[right]);
water += rightMax - height[right];
right--;
}
}
return water;
}
This code calculates how much water can be trapped between bars represented by the array height.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single while loop that moves two pointers from both ends towards the center.
- How many times: The loop runs at most
ntimes, wherenis the number of bars.
As the number of bars increases, the loop runs once per bar, so the total operations grow directly with input size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 loop steps |
| 100 | About 100 loop steps |
| 1000 | About 1000 loop steps |
Pattern observation: The number of steps grows linearly with the number of bars.
Time Complexity: O(n)
This means the time to find trapped water grows in direct proportion to the number of bars.
[X] Wrong: "Because there are two pointers, the time complexity is doubled or quadratic."
[OK] Correct: Both pointers move inward without repeating positions, so total steps are still proportional to n, not n squared.
Understanding this problem's time complexity shows you can analyze two-pointer techniques efficiently, a skill useful in many coding challenges.
"What if we used 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 about water trapped between them.Step 2: Identify what is being calculated
We calculate how much water can be held between bars after it rains, not just heights or counts.Final Answer:
The total amount of water that can be trapped between the bars after raining -> Option AQuick Check:
Trapping Rain Water = Total trapped water [OK]
- Confusing trapped water with max height
- Counting bars taller than neighbors
- Looking for minimum height instead of trapped water
Solution
Step 1: Analyze the input and output types
The input is an array of numbers (heights), output is a single number (total trapped water).Step 2: Match the function signature
Only function trap(height: number[]): number matches input as number array and output as number.Final Answer:
function trap(height: number[]): number -> Option BQuick Check:
Input array, output number [OK]
- Using wrong input type like string or boolean
- Returning array instead of number
- Mismatching input and output types
function trap(height: number[]): number {
let left = 0, right = height.length - 1;
let leftMax = 0, rightMax = 0;
let water = 0;
while (left < right) {
if (height[left] < height[right]) {
height[left] >= leftMax ? (leftMax = height[left]) : water += leftMax - height[left];
left++;
} else {
height[right] >= rightMax ? (rightMax = height[right]) : water += rightMax - height[right];
right--;
}
}
return water;
}
console.log(trap([0,1,0,2,1,0,1,3,2,1,2,1]));Solution
Step 1: Understand the two-pointer approach
We use left and right pointers, track max heights, and accumulate trapped water between bars.Step 2: Trace the code with given input
For input [0,1,0,2,1,0,1,3,2,1,2,1], the trapped water calculated is 6 units.Final Answer:
6 -> Option AQuick Check:
Two-pointer trap water = 6 [OK]
- Miscounting trapped water units
- Confusing leftMax and rightMax updates
- Incorrect pointer movement
function trap(height: number[]): number {
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;
}Solution
Step 1: Check loop boundary conditions
The loop uses 'left <= right' which causes double counting when left equals right.Step 2: Correct the 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 CQuick Check:
Loop boundary fix = correct water count [OK]
- Using <= instead of < in while loop
- Not updating pointers inside loop
- Incorrect water calculation logic
[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, leftMax=0, rightMax=0, water=0.Step 2: Move pointers and calculate trapped water
Iterate:
- left=0 (height=4) > leftMax=0, update leftMax=4, left++
- left=1 (height=2) < leftMax=4, water += 4-2=2, left++
- left=2 (height=0) < leftMax=4, water += 4-0=4, left++
- left=3 (height=3) < leftMax=4, water += 4-3=1, left++
- left=4 (height=2) < leftMax=4, water += 4-2=2, left++
Now left=5 equals right=5, stop.Step 3: Sum trapped water
Total water = 2+4+1+2 = 9 units.Final Answer:
9 -> Option DQuick Check:
Two-pointer trapped water = 9 [OK]
- Only calculating from one side
- Forgetting to update max heights
- Stopping loop too early
Ready to prove it?
Pass the test and this pattern moves unknown
