Trapping Rain Water Using Stack in DSA Typescript - Time & Space Complexity
We want to understand how the time needed to calculate trapped rain water changes as the input size grows.
Specifically, how the use of a stack affects the number of steps as we process the height array.
Analyze the time complexity of the following code snippet.
function trap(height: number[]): number {
const stack: number[] = [];
let water = 0;
for (let i = 0; i < height.length; i++) {
while (stack.length && height[i] > height[stack[stack.length - 1]]) {
const top = stack.pop()!;
if (!stack.length) break;
const distance = i - stack[stack.length - 1] - 1;
const boundedHeight = Math.min(height[i], height[stack[stack.length - 1]]) - height[top];
water += distance * boundedHeight;
}
stack.push(i);
}
return water;
}
This code calculates how much rain water can be trapped between bars of different heights using a stack to track boundaries.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop iterates over each bar once.
- Secondary operation: The while-loop pops bars from the stack when current bar is taller, but each bar is pushed and popped at most once.
- Dominant operation: The combined push and pop operations on the stack happen at most n times each, where n is the number of bars.
As the number of bars increases, each bar is processed a limited number of times.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 stack operations (push + pop) |
| 100 | About 200 stack operations |
| 1000 | About 2000 stack operations |
Pattern observation: The number of operations grows roughly in a straight line with input size, not faster.
Time Complexity: O(n)
This means the time to compute trapped water grows linearly with the number of bars.
[X] Wrong: "The nested while-loop makes this algorithm quadratic (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 while-loop executions across the entire run is at most n, not n times n.
Understanding this linear time solution shows you can use stacks smartly to solve problems efficiently, a skill that impresses in interviews and real projects.
"What if we replaced the stack with a simple nested loop checking all pairs? How would the time complexity change?"
Practice
Trapping Rain Water Using Stack algorithm?Solution
Step 1: Understand the role of stack in the algorithm
The stack stores indices of bars to help find boundaries for trapped water.Step 2: Explain how trapped water is calculated using stack
When a bar higher than the top of the stack is found, water trapped between bars is calculated using indices from the stack.Final Answer:
To keep track of the bars' indices to calculate trapped water -> Option CQuick Check:
Stack stores indices for boundary bars [OK]
- Thinking stack stores heights instead of indices
- Assuming stack sorts the array
- Believing stack holds total water amount
Solution
Step 1: Identify correct TypeScript syntax for stack initialization
Using an array of numbers is the standard way to implement a stack in TypeScript.Step 2: Check each option
const stack: number[] = []; uses a typed empty array which is correct. const stack = new Stack<number>(); assumes a Stack class which is not standard. let stack = {}; initializes an object, not a stack. const stack = Array(); creates an array but without type annotation.Final Answer:
const stack: number[] = []; -> Option DQuick Check:
Typed empty array is correct stack initialization [OK]
- Using object {} instead of array for stack
- Assuming Stack class exists by default
- Not typing the array for clarity
const height = [0,1,0,2,1,0,1,3,2,1,2,1];
function trap(height: number[]): number {
let stack: number[] = [];
let water = 0;
for (let i = 0; i < height.length; i++) {
while (stack.length && height[i] > height[stack[stack.length - 1]]) {
const top = stack.pop()!;
if (!stack.length) break;
const distance = i - stack[stack.length - 1] - 1;
const boundedHeight = Math.min(height[i], height[stack[stack.length - 1]]) - height[top];
water += distance * boundedHeight;
}
stack.push(i);
}
return water;
}
console.log(trap(height));Solution
Step 1: Trace the algorithm with given height array
The algorithm uses a stack to find trapped water between bars. For the given array, the total trapped water is calculated as 6 units.Step 2: Confirm calculation matches known example
This input is a classic example where trapped water is 6 units, matching the output of the code.Final Answer:
6 -> Option BQuick Check:
Classic trapping rain water example = 6 units [OK]
- Miscounting trapped water units
- Ignoring the while loop condition
- Forgetting to break when stack is empty
function trap(height: number[]): number {
let stack: number[] = [];
let water = 0;
for (let i = 0; i <= height.length; i++) {
while (stack.length && height[i] > height[stack[stack.length - 1]]) {
const top = stack.pop()!;
if (!stack.length) break;
const distance = i - stack[stack.length - 1] - 1;
const boundedHeight = Math.min(height[i], height[stack[stack.length - 1]]) - height[top];
water += distance * boundedHeight;
}
stack.push(i);
}
return water;
}Solution
Step 1: Analyze the for loop condition
The loop runs from 0 to height.length inclusive, causing an out-of-bounds access at height[i] when i == height.length.Step 2: Correct the loop condition
Changing the loop condition to i < height.length prevents accessing undefined elements and avoids runtime errors.Final Answer:
The for loop condition should be < instead of <= to avoid out-of-bounds error -> Option AQuick Check:
Loop must stay within array bounds [OK]
- Using <= causes runtime error accessing undefined
- Storing heights instead of indices in stack
- Removing break causes infinite loop
[4,2,0,3,2,5], what is the total amount of trapped rain water calculated using the stack-based algorithm?Solution
Step 1: Use stack to find trapped water between bars
Traverse the array, pushing indices on stack. When current height is greater than top of stack, calculate trapped water between bars using distance and bounded height.Step 2: Calculate trapped water step-by-step
For heights [4,2,0,3,2,5]:
- At i=3: pop 2 (dist=1, boundedHeight=2, water +=2), pop 1 (dist=2, boundedHeight=1, water +=2), total=4
- At i=5: pop 4 (dist=1, boundedHeight=1, water +=1), pop 3 (dist=4, boundedHeight=1, water +=4), total=8Final Answer:
7 -> Option AQuick Check:
Sum trapped water between boundaries = 7 units [OK]
- Missing some trapped water between bars
- Incorrectly calculating distance or bounded height
- Not updating stack correctly during traversal
Ready to prove it?
Pass the test and this pattern moves unknown
