Trapping Rain Water or Water collected between towers : Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
Input - {1,5,2,3,1,7,2} Output - 9 | | | - - - | | - - - | | - | - | | | | - | | | | | | | | | 1 5 2 3 1 7 2 Maximum water in above land can be 9 se - lines between buildings Now Understand for below input Input: arr[] = {3, 0, 0, 2, 0, 4} Output: 10 Structure is like below | | | | | | |__|_| 300204
Algorithm for Trapping Rain Water solution with O(N)
1. For each tower, we try to figure out if there is some unit of rainwater above it, if yes, then what is the amount.
2. Keep adding rainwater amount contribution by each tower to get total rainwater for given set of towers.
Points to Understand :
1. Try visualising the scenario. For rainwater to be on a tower, the height of tower should be less than (one of the tower on its left && one of the tower on its right).
Hence we arrive at our solution:
maxWaterOnCurrentTower = 0 , if there is no tower on left of current tower with more height Or there is no tower on right of current tower with more height else Min(MaxHeightLeft, MaxHeightRight) – currentHeight)
Joining above conditions:
maxWaterOnCurrentTower = Max(Min(MaxHeightLeft, MaxHeightRight) – currentHeight, 0);
Algorithm:
1: With given towerHeight array, create 2 arrays, maxSeenRight and maxSeenLeft.
maxLeft[i] – max height on left side of Tower[i].
maxRight[i] – max height on right side of Tower[i].
2: Calculate for each tower:
rainwater = rainwater + Max(Min(maxLeft[i], maxRight[i]) – towerHeight[i], 0);
import java.util.*; import java.lang.*; import java.io.*; class tappingWater { public static int maxwaterBetweenTowers(int[] arr, int n) { int[] left = new int[n]; int[] right = new int[n]; int collected = 0; right[n - 1] = arr[n - 1]; for (int i = n - 2; i >= 0; i--) right[i] = Math.max(arr[i], right[i + 1]); left[0] = arr[0]; for (int i = 1; i<n; i++) left[i] = Math.max(left[i - 1], arr[i]); for (int i = 0; i<n; i++) collected += Math.min(left[i], right[i]) - arr[i]; return collected; } } public static void main(String[] args) { int[] towerHeight = { 1, 5, 2, 3, 1, 7, 2, 4 }; //int[] towerHeight = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 }; int n = towerHeight.length; System.out.println(maxwaterBetweenTowers(towerHeight,n)); } }