Trapping Rain Water Problem in DSA C# - 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 does the number of operations grow when we have more bars in the elevation map?
Analyze the time complexity of the following code snippet.
public int Trap(int[] height) {
int n = height.Length;
int left = 0, right = n - 1;
int leftMax = 0, rightMax = 0;
int trappedWater = 0;
while (left <= right) {
if (height[left] < height[right]) {
if (height[left] > leftMax) leftMax = height[left];
else trappedWater += leftMax - height[left];
left++;
} else {
if (height[right] > rightMax) rightMax = height[right];
else trappedWater += rightMax - height[right];
right--;
}
}
return trappedWater;
}
This code calculates how much water can be trapped between bars represented by the array.
- Primary operation: A single while loop that moves two pointers across the array.
- How many times: The loop runs at most n times, where n is the number of bars.
As the number of bars increases, the loop runs once per bar, so operations grow linearly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: Doubling the input roughly doubles the work done.
Time Complexity: O(n)
This means the time to solve the problem grows directly in proportion to the number of bars.
[X] Wrong: "Because there are two pointers, the time complexity is O(n²)."
[OK] Correct: Both pointers move inward without repeating positions, so total steps are still just n, not n times n.
Understanding this linear time solution shows you can optimize beyond simple nested loops, a skill valued in problem solving.
"What if we used two separate loops to precompute leftMax and rightMax arrays before calculating trapped water? 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 how much water can be trapped after raining.Step 2: Identify the goal
The goal is to calculate the total trapped water volume between bars, not just heights or counts.Final Answer:
The total amount of water that can be trapped between the bars. -> Option DQuick Check:
Trapping Rain Water = Total trapped water [OK]
- Confusing trapped water with maximum bar height
- Counting bars instead of calculating water volume
- Ignoring the space between bars
Solution
Step 1: Check array initialization syntax in C#
Correct syntax uses int[] variable = new int[] {values};Step 2: Validate each option
int[] heights = new int[] {4, 2, 0, 3, 2, 5}; uses correct syntax; B and C have invalid syntax; D has incorrect array declaration style.Final Answer:
int[] heights = new int[] {4, 2, 0, 3, 2, 5}; -> Option AQuick Check:
C# array init = new int[] {values} [OK]
- Missing 'new int[]' keyword
- Using parentheses instead of braces
- Incorrect array declaration syntax
int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
int trappedWater = Trap(height);
Console.WriteLine(trappedWater);
int Trap(int[] height) {
int left = 0, right = height.Length - 1;
int leftMax = 0, rightMax = 0;
int 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: Understand two-pointer approach in code
Left and right pointers move inward, tracking max heights and accumulating trapped water.Step 2: Trace the code with given input
For input {0,1,0,2,1,0,1,3,2,1,2,1}, trapped water calculated is 6 units.Final Answer:
6 -> Option BQuick Check:
Two-pointer trap water = 6 [OK]
- Miscounting trapped water units
- Confusing leftMax and rightMax updates
- Incorrect pointer movement logic
int Trap(int[] height) {
int left = 0, right = height.Length - 1;
int leftMax = 0, rightMax = 0;
int 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: Analyze loop condition impact
Using 'left <= right' causes double counting when left equals right, leading to incorrect water calculation.Step 2: Correct loop condition
Changing to 'left < right' prevents overlap and fixes the bug.Final Answer:
The loop condition should be 'left < right' instead of 'left <= right'. -> Option AQuick Check:
Loop condition 'left < right' avoids double counting [OK]
- Using <= causes overlap and wrong water sum
- Changing comparison operators unnecessarily
- Moving water calculation outside conditions
{5, 2, 1, 2, 1, 5}, what is the total trapped rain water? Explain why the trapped water forms in this case.Solution
Step 1: Calculate trapped water at each position
Left max array: [5,5,5,5,5,5], Right max array: [5,5,5,5,5,5]. Water trapped = min(leftMax, rightMax) - height at each index: positions 1=3, 2=4, 3=3, 4=4.Step 2: Sum trapped water and explain formation
Total trapped water = 3+4+3+4 = 14 units. Water forms because tall bars at ends trap water over lower bars inside.Final Answer:
14 -> Option CQuick Check:
Sum trapped water = 14 units [OK]
- Ignoring max heights on both sides
- Calculating trapped water incorrectly per position
- Forgetting to sum all trapped units
Ready to prove it?
Pass the test and this pattern moves unknown
