I recently came across an interview question asked by Amazon and I am not able to find an optimized algorithm to solve this question:
You are given an input array wh
An intuitive solution for this problem is one in which you bound the problem and fill water based on the height of the left and right bounds.
My solution:
Here is an implementation in C#:
int[] towers = {1,5,3,7,2};
int currentMinimum = towers[0];
bool rightBoundFound = false;
int i = 0;
int leftBoundIndex = 0;
int rightBoundIndex = 0;
int waterAdded = 0;
while(i < towers.Length - 1)
{
currentMinimum = towers[i];
if(towers[i] < currentMinimum)
{
currentMinimum = towers[i];
}
if(towers[i + 1] > towers[i])
{
rightBoundFound = true;
rightBoundIndex = i + 1;
}
if (rightBoundFound)
{
for(int j = leftBoundIndex + 1; j < rightBoundIndex; j++)
{
int difference = 0;
if(towers[leftBoundIndex] < towers[rightBoundIndex])
{
difference = towers[leftBoundIndex] - towers[j];
}
else if(towers[leftBoundIndex] > towers[rightBoundIndex])
{
difference = towers[rightBoundIndex] - towers[j];
}
else
{
difference = towers[rightBoundIndex] - towers[j];
}
towers[j] += difference;
waterAdded += difference;
}
if (towers[leftBoundIndex] > towers[rightBoundIndex])
{
i = leftBoundIndex - 1;
}
else if (towers[rightBoundIndex] > towers[leftBoundIndex])
{
leftBoundIndex = rightBoundIndex;
i = rightBoundIndex - 1;
}
else
{
leftBoundIndex = rightBoundIndex;
i = rightBoundIndex - 1;
}
rightBoundFound = false;
}
i++;
}
I have no doubt that there are more optimal solutions. I am currently working on a single-pass optimization. There is also a very neat stack implementation of this problem, and it uses a similar idea of bounding.