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 steps increase when using a stack to solve this problem.
Analyze the time complexity of the following code snippet.
int trap(vector<int>& height) {
stack<int> st;
int water = 0;
for (int i = 0; i < height.size(); i++) {
while (!st.empty() && height[i] > height[st.top()]) {
int top = st.top(); st.pop();
if (st.empty()) break;
int distance = i - st.top() - 1;
int bounded_height = min(height[i], height[st.top()]) - height[top];
water += distance * bounded_height;
}
st.push(i);
}
return water;
}
This code calculates how much rainwater can be trapped between bars using a stack to track boundaries.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop iterates over each bar once.
- Nested operation: The 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 stack operations are proportional to input size.
As the number of bars increases, the for-loop runs once per bar, and the while-loop pops bars only when needed.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 stack operations |
| 100 | About 200 stack operations |
| 1000 | About 2000 stack operations |
Pattern observation: The total operations grow roughly in a straight line with input size.
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 O(n²)."
[OK] Correct: Each bar is pushed and popped only once, so total stack operations add up to O(n), not n times n.
Understanding this linear time solution shows you can use stacks smartly to solve tricky problems efficiently.
"What if we used a simple nested loop without 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: Explain why other options are incorrect
The stack does not store water amount or sort bars; it helps track bars for water calculation.Final Answer:
To keep track of bars that are not yet processed for water trapping -> Option BQuick Check:
Stack tracks bars for trapping water = A [OK]
- Thinking stack stores water amount
- Assuming stack sorts bars
- Confusing stack with array for heights
Solution
Step 1: Check correct C++ stack declaration syntax
Correct syntax isstd::stack<int> st;to declare a stack of integers.Step 2: Identify errors in other options
stack<int> st = new stack<int>(); uses incorrect syntax with 'new'; C has wrong template placement; D declares a function, not a stack.Final Answer:
std::stack<int> st; -> Option AQuick Check:
Correct stack declaration = B [OK]
- Using 'new' keyword incorrectly
- Wrong template syntax
- Declaring function instead of stack
int height[] = {0,1,0,2,1,0,1,3,2,1,2,1};
int n = 12;
std::stack<int> st;
int water = 0;
for (int i = 0; i < n; i++) {
while (!st.empty() && height[i] > height[st.top()]) {
int top = st.top();
st.pop();
if (st.empty()) break;
int distance = i - st.top() - 1;
int bounded_height = std::min(height[i], height[st.top()]) - height[top];
water += distance * bounded_height;
}
st.push(i);
}
std::cout << water << std::endl;Solution
Step 1: Trace the stack operations and water calculation
The code calculates trapped water for the given heights array using stack logic. The total trapped water is 6 units.Step 2: Verify calculations with known example
This is a classic example where trapped water is 6 units, matching the output of the code.Final Answer:
6 -> Option CQuick Check:
Trapped water = 6 [OK]
- Miscounting distance between bars
- Wrong bounded height calculation
- Ignoring empty stack break condition
std::stack<int> st;
int water = 0;
for (int i = 0; i < height.size(); i++) {
while (!st.empty() && height[i] >= height[st.top()]) {
int top = st.top();
st.pop();
if (st.empty()) break;
int distance = i - st.top() - 1;
int bounded_height = std::min(height[i], height[st.top()]) - height[top];
water += distance * bounded_height;
}
st.push(i);
}
std::cout << water << std::endl;Solution
Step 1: Analyze the while loop condition
The condition uses >= which causes popping bars of equal height, leading to incorrect trapped water calculation.Step 2: Explain correct condition and impact
Using > ensures only bars lower than current are popped, preserving correct boundaries for water trapping.Final Answer:
Using >= instead of > in while condition causes incorrect water calculation -> Option DQuick Check:
Use > not >= in while condition [OK]
- Using >= instead of > in while condition
- Storing heights instead of indices in stack
- Forgetting break when stack is empty
{4, 2, 0, 3, 2, 5}, what is the total trapped rain water calculated using the stack approach?Solution
Step 1: Calculate trapped water between bars using stack logic
Between bars, trapped water units are: 2 units between 4 and 3, 1 unit between 3 and 5, and 5 units between 2 and 5, totaling 8 units.Step 2: Sum trapped water units
Sum of trapped water is 8 units for the given array.Final Answer:
8 -> Option AQuick Check:
Trapped water total = 8 [OK]
- Ignoring zero height bars
- Miscounting trapped water between bars
- Not considering both left and right boundaries
Ready to prove it?
Pass the test and this pattern moves unknown
