/* package whatever; // don't place package name! */
import java.util.Stack;
/**
*
* Prateek
* */
class TrapRainWater {
public static void main
(String[] args
) { //int[] bars = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
int[] bars = {3, 0, 0, 2, 0, 4};
System.
out.
println(trapWaterUsingBrute
(bars
)); System.
out.
println(trapWaterUsingDP
(bars
)); System.
out.
println(trapWaterUsingStack
(bars
)); System.
out.
println(trapWaterUsingPointers
(bars
)); }
//Using the two pointer based approach to trap water
static int trapWaterUsingPointers(int[] height) {
if(height == null || height.length < 3)
return 0;
int l = 0, r = height.length-1; // Two pointers which will switched for movement
int lmax = height[0] , rmax = height[height.length-1];
int trappedWater = 0;
while (l < r) {
if (height[l] < height[r]) {
if (height[l] >= lmax) {
lmax = height[l]; //increment but dont count water
} else {
trappedWater += lmax - height[l];
}
l++;
} else {
if (height[r] >= rmax) {
rmax = height[r]; //decrement but dont count water
} else {
trappedWater += rmax - height[r];
}
r--;
}
}
return trappedWater;
}
//Stack based Approach to Trap rain water problem solution
static int trapWaterUsingStack(int[] bars) {
if(bars == null || bars.length < 3)
return 0;
Stack<Integer> stack = new Stack<>();
stack.push(0);
int len = bars.length, waterTrapped = 0;
for(int i=1; i < len ; i++)
{
while(!stack.isEmpty() && bars[stack.peek()] < bars[i]) {
int top = stack.pop();
if(!stack.isEmpty()) {
int dist = stack.isEmpty() ? 0 : i - stack.peek() - 1 ;
int effectiveHeight
= Math.
min(bars
[i
], bars
[stack.
peek()]) - bars
[top
]; waterTrapped += dist * effectiveHeight;
}
}
stack.push(i);
}
return waterTrapped;
}
// Brute Force Approach
static int trapWaterUsingBrute(int[] bars) {
int len = bars.length;
int trappedWater = 0;
for (int i = 1; i < len - 1; i++) {
int lmax = 0, rmax = 0;
for (int j = i - 1; j >= 0; j--)
lmax
= Math.
max(lmax, bars
[j
]);
for (int j = i + 1; j < len; j++)
rmax
= Math.
max(rmax, bars
[j
]);
trappedWater
+= Math.
max(0,
Math.
min(lmax, rmax
) - bars
[i
]); }
return trappedWater;
}
//Dynamic Programming Apporach to Trap rain water problem solution
static int trapWaterUsingDP(int[] bars) {
if(bars == null || bars.length < 3)
return 0;
int len = bars.length, trappedWater = 0;
int[] left = new int[len];
int[] right = new int[len];
//NB. for left most bar lmax would be 0, so counter is stated with 1,
for(int i=1;i<len;i++)
left
[i
] = Math.
max(left
[i
-1], bars
[i
-1]);
// similarly for right most bar rmax would be 0 at len-1.
for(int i= len -2 ;i >= 0;i--)
right
[i
] = Math.
max(right
[i
+1], bars
[i
+1]);
for(int i=0;i<len;i++)
trappedWater
+= Math.
max(0,
Math.
min(left
[i
], right
[i
]) - bars
[i
]);
return trappedWater;
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKCmltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci8qKgogKiAKICogUHJhdGVlayAKICogKi8KY2xhc3MgVHJhcFJhaW5XYXRlciB7CgoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewoJCS8vaW50W10gYmFycyA9IHswLCAxLCAwLCAyLCAxLCAwLCAxLCAzLCAyLCAxLCAyLCAxfTsKCQlpbnRbXSBiYXJzID0gezMsIDAsIDAsIDIsIDAsIDR9OwoJCVN5c3RlbS5vdXQucHJpbnRsbih0cmFwV2F0ZXJVc2luZ0JydXRlKGJhcnMpKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4odHJhcFdhdGVyVXNpbmdEUChiYXJzKSk7CgkJU3lzdGVtLm91dC5wcmludGxuKHRyYXBXYXRlclVzaW5nU3RhY2soYmFycykpOwoJCVN5c3RlbS5vdXQucHJpbnRsbih0cmFwV2F0ZXJVc2luZ1BvaW50ZXJzKGJhcnMpKTsKCX0KCQoKCS8vVXNpbmcgdGhlIHR3byBwb2ludGVyIGJhc2VkIGFwcHJvYWNoIHRvIHRyYXAgd2F0ZXIKCXN0YXRpYyBpbnQgdHJhcFdhdGVyVXNpbmdQb2ludGVycyhpbnRbXSBoZWlnaHQpIHsKCQlpZihoZWlnaHQgPT0gbnVsbCB8fCBoZWlnaHQubGVuZ3RoIDwgMykgCgkgICAgIAkJcmV0dXJuIDA7CgkJCgkJaW50IGwgPSAwLCByID0gaGVpZ2h0Lmxlbmd0aC0xOyAvLyBUd28gcG9pbnRlcnMgd2hpY2ggd2lsbCBzd2l0Y2hlZCBmb3IgbW92ZW1lbnQgCgkJaW50IGxtYXggPSBoZWlnaHRbMF0gLCBybWF4ID0gaGVpZ2h0W2hlaWdodC5sZW5ndGgtMV07CgkJCgkJaW50IHRyYXBwZWRXYXRlciA9IDA7CgkJCgkJd2hpbGUgKGwgPCByKSB7CgkJCWlmIChoZWlnaHRbbF0gPCBoZWlnaHRbcl0pIHsKCQkJCWlmIChoZWlnaHRbbF0gPj0gbG1heCkgeyAgCgkJCQkJbG1heCA9IGhlaWdodFtsXTsgLy9pbmNyZW1lbnQgYnV0IGRvbnQgY291bnQgd2F0ZXIKCQkJCX0gZWxzZSB7CgkJCQkJdHJhcHBlZFdhdGVyICs9IGxtYXggLSBoZWlnaHRbbF07CgkJCQl9CgkJCQlsKys7CgkJCX0gZWxzZSB7CgkJCQlpZiAoaGVpZ2h0W3JdID49IHJtYXgpIHsKCQkJCQlybWF4ID0gaGVpZ2h0W3JdOyAgLy9kZWNyZW1lbnQgYnV0IGRvbnQgY291bnQgd2F0ZXIKCQkJCX0gZWxzZSB7CgkJCQkJdHJhcHBlZFdhdGVyICs9IHJtYXggLSBoZWlnaHRbcl07CgkJCQl9CgkJCQlyLS07CgkJCX0KCQl9CgkJcmV0dXJuIHRyYXBwZWRXYXRlcjsKCX0KCQogICAgIC8vU3RhY2sgYmFzZWQgQXBwcm9hY2ggdG8gVHJhcCByYWluIHdhdGVyIHByb2JsZW0gc29sdXRpb24KICAgICBzdGF0aWMgaW50IHRyYXBXYXRlclVzaW5nU3RhY2soaW50W10gYmFycykgewogICAgCSBpZihiYXJzID09IG51bGwgfHwgYmFycy5sZW5ndGggPCAzKSAKICAgICAJCXJldHVybiAwOwogICAgCSAKICAgIAkgU3RhY2s8SW50ZWdlcj4gc3RhY2sgPSBuZXcgU3RhY2s8PigpOwogICAgCSBzdGFjay5wdXNoKDApOwogICAgCSAKICAgIAkgaW50IGxlbiA9IGJhcnMubGVuZ3RoLCB3YXRlclRyYXBwZWQgPSAwOwogICAgCSBmb3IoaW50IGk9MTsgaSA8IGxlbiA7IGkrKykKICAgIAkgewogICAgCQkgd2hpbGUoIXN0YWNrLmlzRW1wdHkoKSAmJiBiYXJzW3N0YWNrLnBlZWsoKV0gPCBiYXJzW2ldKSB7CiAgICAJCQkgaW50IHRvcCA9IHN0YWNrLnBvcCgpOwogICAgCQkJIGlmKCFzdGFjay5pc0VtcHR5KCkpIHsKICAgIAkJCQkgaW50IGRpc3QgPSBzdGFjay5pc0VtcHR5KCkgPyAgMCA6IGkgLSBzdGFjay5wZWVrKCkgLSAxIDsKICAgIAkJCQkgaW50IGVmZmVjdGl2ZUhlaWdodCA9IE1hdGgubWluKGJhcnNbaV0sIGJhcnNbc3RhY2sucGVlaygpXSkgLSBiYXJzW3RvcF07CiAgICAgICAgCQkJIHdhdGVyVHJhcHBlZCArPSBkaXN0ICogZWZmZWN0aXZlSGVpZ2h0OwogICAgCQkJIH0KICAgIAkJIH0KICAgIAkJIHN0YWNrLnB1c2goaSk7CiAgICAJIH0KICAgIAkgcmV0dXJuIHdhdGVyVHJhcHBlZDsKICAgICB9CiAgICAgCiAgICAgCiAJLy8gQnJ1dGUgRm9yY2UgQXBwcm9hY2gKIAlzdGF0aWMgaW50IHRyYXBXYXRlclVzaW5nQnJ1dGUoaW50W10gYmFycykgewogCQlpbnQgbGVuID0gYmFycy5sZW5ndGg7CiAJCWludCB0cmFwcGVkV2F0ZXIgPSAwOwogCQlmb3IgKGludCBpID0gMTsgaSA8IGxlbiAtIDE7IGkrKykgewogCQkJaW50IGxtYXggPSAwLCBybWF4ID0gMDsKCiAJCQlmb3IgKGludCBqID0gaSAtIDE7IGogPj0gMDsgai0tKQogCQkJCWxtYXggPSBNYXRoLm1heChsbWF4LCBiYXJzW2pdKTsKCiAJCQlmb3IgKGludCBqID0gaSArIDE7IGogPCBsZW47IGorKykKIAkJCQlybWF4ID0gTWF0aC5tYXgocm1heCwgYmFyc1tqXSk7CgogCQkJdHJhcHBlZFdhdGVyICs9IE1hdGgubWF4KDAsIE1hdGgubWluKGxtYXgsIHJtYXgpIC0gYmFyc1tpXSk7CiAJCX0KIAkJcmV0dXJuIHRyYXBwZWRXYXRlcjsKIAl9CiAgICAgCiAgICAgIC8vRHluYW1pYyBQcm9ncmFtbWluZyBBcHBvcmFjaCB0byBUcmFwIHJhaW4gd2F0ZXIgcHJvYmxlbSBzb2x1dGlvbgogICAgICBzdGF0aWMgaW50IHRyYXBXYXRlclVzaW5nRFAoaW50W10gYmFycykgewogICAgIAlpZihiYXJzID09IG51bGwgfHwgYmFycy5sZW5ndGggPCAzKSAKICAgICAJCXJldHVybiAwOwogICAgIAkKICAgICAJaW50IGxlbiA9IGJhcnMubGVuZ3RoLCB0cmFwcGVkV2F0ZXIgPSAwOwogICAgIAlpbnRbXSBsZWZ0ID0gbmV3IGludFtsZW5dOwogICAgIAlpbnRbXSByaWdodCA9IG5ldyBpbnRbbGVuXTsKICAgICAJCiAgICAgCS8vTkIuIGZvciBsZWZ0IG1vc3QgYmFyIGxtYXggd291bGQgYmUgMCwgc28gY291bnRlciBpcyBzdGF0ZWQgd2l0aCAxLAogICAgIAlmb3IoaW50IGk9MTtpPGxlbjtpKyspIAogICAgIAkJbGVmdFtpXSA9IE1hdGgubWF4KGxlZnRbaS0xXSwgYmFyc1tpLTFdKTsKICAgICAJCiAgICAgCS8vIHNpbWlsYXJseSBmb3IgcmlnaHQgbW9zdCBiYXIgcm1heCB3b3VsZCBiZSAwIGF0IGxlbi0xLiAKICAgICAJZm9yKGludCBpPSBsZW4gLTIgO2kgPj0gMDtpLS0pIAogICAgIAkJcmlnaHRbaV0gPSBNYXRoLm1heChyaWdodFtpKzFdLCBiYXJzW2krMV0pOwogICAgIAkKICAgICAJCiAgICAgCWZvcihpbnQgaT0wO2k8bGVuO2krKykKICAgICAJCXRyYXBwZWRXYXRlciArPSBNYXRoLm1heCgwLCBNYXRoLm1pbihsZWZ0W2ldLCByaWdodFtpXSkgLSBiYXJzW2ldKTsKICAgICAJCiAgICAgCXJldHVybiB0cmFwcGVkV2F0ZXI7CiAgICAgfQogICAgICAKfQo=