Discover how a simple stack can solve a tricky water trapping puzzle faster than you think!
Why Trapping Rain Water Using Stack in DSA Rust?
Imagine you have a row of buildings with different heights after a rainstorm. You want to find out how much water is trapped between these buildings. Trying to calculate this by checking each gap manually is like measuring puddles one by one without a clear method.
Manually checking each space between buildings is slow and confusing. You might miss some trapped water or count it twice. It's easy to make mistakes because you have to remember the heights on both sides and how water fills up.
Using a stack helps you keep track of building heights in a smart way. The stack remembers where water can be trapped, so you only calculate when you find a taller building that can hold water. This method is faster and less error-prone.
let mut total_water = 0; for i in 1..heights.len()-1 { let left_max = heights[..i].iter().max().unwrap_or(&0); let right_max = heights[i+1..].iter().max().unwrap_or(&0); let water = (*left_max).min(*right_max) - heights[i]; if water > 0 { total_water += water; } }
let mut stack = Vec::new(); let mut total_water = 0; for current in 0..heights.len() { while let Some(&top) = stack.last() { if heights[current] > heights[top] { let bottom = stack.pop().unwrap(); if let Some(&left) = stack.last() { let distance = current - left - 1; let bounded_height = heights[current].min(heights[left]) - heights[bottom]; if bounded_height > 0 { total_water += distance * bounded_height; } } else { break; } } else { break; } } stack.push(current); }
This method lets you quickly and accurately find how much rainwater is trapped between buildings, even in complex shapes.
City planners can use this to understand how water collects in urban areas after rain, helping design better drainage systems.
Manual checking is slow and error-prone.
Stack keeps track of boundaries to trap water efficiently.
Stack method is faster and less confusing for complex height patterns.
Practice
Trapping Rain Water Using Stack algorithm?Solution
Step 1: Understand the role of stack in the algorithm
The stack stores indices of bars that are waiting to find a right boundary to trap water.Step 2: Clarify what the stack does not do
The stack does not store water amount or sort bars; it helps find boundaries for trapped water.Final Answer:
To keep track of bars that are not yet processed for water trapping -> Option CQuick Check:
Stack tracks bars for trapping water = D [OK]
- Thinking stack stores water amount
- Assuming stack sorts the bars
- Believing stack reverses bar order
Solution
Step 1: Identify correct stack declaration for indices
Indices are usize type, so stack must be Vec<usize> and mutable to push/pop.Step 2: Check each option
let mut stack: Vec<usize> = Vec::new(); correctly declares mutable Vec<usize> empty stack. let stack = Vec::with_capacity(10); is immutable and no mut keyword. let stack = vec![0]; initializes with one element, not empty. let mut stack: Vec<i32> = Vec::new(); uses i32 instead of usize for indices.Final Answer:
let mut stack: Vec<usize> = Vec::new(); -> Option BQuick Check:
Mutable Vec<usize> empty stack = A [OK]
- Using wrong type like i32 for indices
- Not making stack mutable
- Initializing stack with elements instead of empty
fn trap(height: Vec<i32>) -> i32 {
let mut stack: Vec<usize> = Vec::new();
let mut water = 0;
for i in 0..height.len() {
while !stack.is_empty() && height[i] > height[*stack.last().unwrap()] {
let top = stack.pop().unwrap();
if stack.is_empty() {
break;
}
let distance = i - *stack.last().unwrap() - 1;
let bounded_height = height[i].min(height[*stack.last().unwrap()]) - height[top];
water += (distance as i32) * bounded_height;
}
stack.push(i);
}
water
}
let heights = vec![0,1,0,2,1,0,1,3,2,1,2,1];
println!("{}", trap(heights));Solution
Step 1: Understand the input and algorithm
The input heights represent bars: [0,1,0,2,1,0,1,3,2,1,2,1]. The stack-based algorithm calculates trapped water by finding bounded areas.Step 2: Calculate trapped water step-by-step
The known trapped water for this input is 6 units, as the algorithm sums water trapped between bars correctly.Final Answer:
6 -> Option AQuick Check:
Trapped water for given heights = 6 [OK]
- Miscounting trapped water units
- Ignoring boundary conditions
- Incorrectly calculating distance or height
fn trap(height: Vec<i32>) -> i32 {
let mut stack: Vec<usize> = Vec::new();
let mut water = 0;
for i in 0..height.len() {
while !stack.is_empty() && height[i] > height[*stack.last().unwrap()] {
let top = stack.pop().unwrap();
if stack.is_empty() {
break;
}
let distance = i - *stack.last().unwrap() - 1;
let bounded_height = height[i].min(height[*stack.last().unwrap()]) - height[top];
water += distance * bounded_height;
}
stack.push(i);
}
water
}Solution
Step 1: Identify type mismatch in multiplication
distance is usize, bounded_height is i32; multiplying usize * i32 causes type error in Rust.Step 2: Fix by casting distance to i32 before multiplication
Cast distance as i32: (distance as i32) * bounded_height to fix type mismatch.Final Answer:
Change water += distance * bounded_height; to water += (distance as i32) * bounded_height; -> Option DQuick Check:
Cast usize to i32 before multiply = C [OK]
- Ignoring type mismatch errors
- Removing necessary empty stack check
- Changing comparison operator incorrectly
[4, 2, 0, 3, 2, 5], what is the total trapped rain water calculated by the stack-based algorithm?Solution
Step 1: Visualize the bars and trapped water
Bars heights: 4, 2, 0, 3, 2, 5. Water trapped between bars is calculated by stack algorithm using boundaries.Step 2: Calculate trapped water stepwise
Using min(left_max, right_max) - height[i] for each i:
- i=1: min(4,5)-2=2
- i=2: min(4,5)-0=4
- i=3: min(4,5)-3=1
- i=4: min(4,5)-2=2
Total trapped water = 9 units.Final Answer:
9 -> Option AQuick Check:
Sum trapped water units = 9 [OK]
- Miscounting water units between bars
- Ignoring zero height bars
- Not considering both left and right boundaries
Ready to prove it?
Pass the test and this pattern moves unknown
