Trapping Rain Water Using Stack in DSA C# - 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 number of steps grows when using a stack to solve this problem.
Analyze the time complexity of the following code snippet.
public int Trap(int[] height) {
int water = 0, current = 0;
Stack<int> stack = new Stack<int>();
while (current < height.Length) {
while (stack.Count > 0 && height[current] > height[stack.Peek()]) {
int top = stack.Pop();
if (stack.Count == 0) break;
int distance = current - stack.Peek() - 1;
int boundedHeight = Math.Min(height[current], height[stack.Peek()]) - height[top];
water += distance * boundedHeight;
}
stack.Push(current++);
}
return water;
}
This code calculates how much rain water can be trapped between bars using a stack to track boundaries.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The outer while loop runs through each bar once.
- Inner loop: The inner while loop pops bars from the stack when current bar is taller.
- How many times: Each bar is pushed and popped at most once, so total operations scale with number of bars.
As the number of bars increases, the total steps increase roughly in a straight line.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 steps (push and pop each bar once) |
| 100 | About 200 steps |
| 1000 | About 2000 steps |
Pattern observation: The operations grow linearly with input size because each bar is processed a limited number of times.
Time Complexity: O(n)
This means the time to calculate trapped water grows directly in proportion to the number of bars.
[X] Wrong: "The inner loop causes the time to be quadratic because it can run many times inside the outer loop."
[OK] Correct: Each bar is pushed and popped only once, so total inner loop executions across all iterations add up to n, not n squared.
Understanding this linear time solution shows you can use stacks smartly to solve problems efficiently, a skill valued in many coding challenges.
"What if we replaced the stack with a simple array and scanned multiple times? 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 for a right boundary to trap water.Step 2: Explain why other options are incorrect
The stack does not store water amount, sort, or reverse the array; it helps find boundaries.Final Answer:
To keep track of bars that are not yet processed for water trapping -> Option AQuick Check:
Stack tracks bars for trapping water = A [OK]
- Thinking stack stores water amount directly
- Assuming stack sorts or reverses the array
- Confusing stack with a queue
Solution
Step 1: Identify correct stack declaration
Stack<int> stack = new Stack<int>(); uses generic Stack<int> which is type-safe and correct for storing indices.Step 2: Explain why others are incorrect
Stack stack = new Stack(); is non-generic and less type-safe; C uses List, not stack; D uses Queue, wrong data structure.Final Answer:
Stack<int> stack = new Stack<int>(); -> Option BQuick Check:
Generic Stack<int> is correct stack declaration [OK]
- Using non-generic Stack without type safety
- Using List instead of Stack
- Confusing Queue with Stack
int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
int water = 0;
Stack<int> stack = new Stack<int>();
for (int i = 0; i < height.Length; i++) {
while (stack.Count > 0 && height[i] > height[stack.Peek()]) {
int top = stack.Pop();
if (stack.Count == 0) break;
int distance = i - stack.Peek() - 1;
int boundedHeight = Math.Min(height[i], height[stack.Peek()]) - height[top];
water += distance * boundedHeight;
}
stack.Push(i);
}
Console.WriteLine(water);Solution
Step 1: Trace the stack operations and water calculation
The code calculates trapped water for the given height array using stack logic. The total trapped water is 6 units.Step 2: Confirm calculation matches known example
This is a classic example where trapped water is known to be 6 units for the given heights.Final Answer:
6 -> Option DQuick Check:
Trapped water for given heights = 6 [OK]
- Miscounting distance or bounded height
- Forgetting to check stack empty before popping
- Mixing up indices and heights
int[] height = {4,2,0,3,2,5};
int water = 0;
Stack<int> stack = new Stack<int>();
for (int i = 0; i < height.Length; i++) {
while (stack.Count > 0 && height[i] >= height[stack.Peek()]) {
int top = stack.Pop();
if (stack.Count == 0) break;
int distance = i - stack.Peek() - 1;
int boundedHeight = Math.Min(height[i], height[stack.Peek()]) - height[top];
water += distance * boundedHeight;
}
stack.Push(i);
}
Console.WriteLine(water);Solution
Step 1: Analyze the while loop condition
The condition uses >= which causes incorrect popping when heights are equal, leading to wrong water calculation.Step 2: Correct condition and explain impact
Changing >= to > fixes the logic by only popping when current height is strictly greater, preserving correct boundaries.Final Answer:
The comparison should be > instead of >= in the while condition -> Option CQuick Check:
Use > not >= in while condition [OK]
- Using >= causes extra pops and wrong water
- Confusing stack with queue
- Incorrect distance or boundedHeight formulas
int[] height = {5,2,1,2,1,5};, what is the total trapped rain water calculated using the stack-based algorithm?Solution
Step 1: Visualize trapped water between bars
Between the two 5-height bars at ends, water is trapped over lower bars: (5-2)+(5-1)+(5-2)+(5-1) = 3+4+3+4 but we must count carefully by positions.Step 2: Calculate trapped water using stack logic
Trapped water units are 3 (between 5 and 2), 1 (between 2 and 1), 3 (between 2 and 1), and 5 (between 1 and 5), total 12 units.Final Answer:
12 -> Option AQuick Check:
Trapped water total = 12 units [OK]
- Adding heights instead of differences
- Ignoring boundaries at array ends
- Miscounting trapped water units
Ready to prove it?
Pass the test and this pattern moves unknown
