Trapping rain water problem
Written by
Trapping rain water problem
Input: [1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can be trapped after raining.
The above problem statement can be a bit perplexing – so see the below picture for reference.
Each square of water trapped is 1 unit.
Instead of directly aiming for Efficient Solution, we aim for a solution firsthand. To quote Donald Knuth, the great computer scientist “Premature Optimization is the root for all evil”.
This problem has 3 main approaches. But firstly, we see the brute force approach, and then we go on improving some bits and parts of our code.
# Brute Force
Herein, we simply aim for the solution, no matter the cost. So, devising a pseudo code for this:
- Maintain two indices, one to iterate on the length of elevation or tower at the index, and other to calculate the water at a particular index.
- Iterate till length :
a. Store the max length of the buildings to the left and to the right of the index.
b. The shorter of the two is taken as the level till which the water can rise.
c. Decrease the height of the building at current index - Summation of water collected at all indices gives us the total water.
Code:
#include <iostream>
#include <algorithm>
using namespace std;
void bruteForceRainwater(int buildingArray[], int size)
{
if (size == 1 || size == 0)
{
cout << "Sorry";
return;
}
int index, waterAtCurrent, totalWater = 0;
for (index = 1; index < size - 1; index++) // as will iterate till second last, water can never be stored at the first and the last
{
int left = buildingArray[index];
for (int j = 0; j < index; j++)
left = max(left, buildingArray[j]);
// Find the maximum element on its right
int right = buildingArray[index];
for (int j = index + 1; j < size; j++)
right = max(right, buildingArray[j]);
int waterLevel = (min(left, right)) - buildingArray[index];
if (waterLevel >= 0)
waterAtCurrent = waterLevel;
else
waterAtCurrent = 0;
totalWater += waterAtCurrent;
}
cout << "Total Water is :";
cout << totalWater;
}
int main()
{
int buildings[] = { 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
bruteForceRainwater(buildings, 11);
return 0;
}
Time complexity : O(n2).
Space complexity: O(1)
# Improvement on Time Complexity
We try to reduce the time complexity here.
Code:
#include <iostream>
#include <algorithm>
using namespace std;
void reduceTimeRainwater(int buildingArray[], int size)
{
if (size == 1 || size == 0)
{
cout << "Sorry";
return;
}
int index, waterAtCurrent, totalWater = 0;
int leftArray[size], rightArray[size];
leftArray[0] = buildingArray[0];
for (int i = 1; i < size; i++)
leftArray[i] = max(leftArray[i - 1], buildingArray[i]);
rightArray[size - 1] = buildingArray[size - 1];
for (int i = size - 2; i >= 0; i--)
rightArray[i] = max(rightArray[i + 1], buildingArray[i]);
for (index = 1; index < size; index++)
{
waterAtCurrent = min(leftArray[index], rightArray[index]) - buildingArray[index];
totalWater += waterAtCurrent;
}
cout << "Total Water is :" << totalWater;
}
int main()
{
int buildings[] = { 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
reduceTimeRainwater(buildings, 11);
return 0;
}
Time complexity: O(n)
Space complexity: O(n)
# Decreasing the auxiliary space required
This is the most efficient solution, with us minimizing the spacing required by our program.
Code:
#include <iostream>
using namespace std;
int findWater(int buildingArray[], int n)
{
int totalWater = 0;
int left = 0, right = 0;
int low = 0, high = n - 1;
whighle(low <= high)
{
if (buildingArray[low] < buildingArray[high])
{
if (buildingArray[low] > left)
// update max in left
left = buildingArray[low];
else
totalWater += left - buildingArray[low];
low++;
}
else
{
if (buildingArray[high] > right)
// update right maximum
right = buildingArray[high];
else
totalWater += right - buildingArray[high];
high--;
}
}
cout << "Total Water is " << totalWater;
}
int main()
{
int[] buildings = { 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
optimizedSpaceRainwater(buildings, 11);
}
Time complexity :O(n)
Space complexity :O(1)
Output :
Total Water is: 6
This is how we solve the trapping rainwater problem.