LeetCode – Trapping Rain Water (Java)

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.

For example, given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

Analysis

This problem is similar to Candy. It can be solve by scanning from both sides and then get the total.

Java Solution

public int trap(int[] height) {
    int result = 0;
 
    if(height==null || height.length<=2)
        return result;
 
    int left[] = new int[height.length];
    int right[]= new int[height.length];
 
    //scan from left to right
    int max = height[0];
    left[0] = height[0];
    for(int i=1; i<height.length; i++){
        if(height[i]<max){
            left[i]=max;
        }else{
            left[i]=height[i];
            max = height[i];
        }
    }
 
    //scan from right to left
    max = height[height.length-1];
    right[height.length-1]=height[height.length-1];
    for(int i=height.length-2; i>=0; i--){
        if(height[i]<max){
            right[i]=max;
        }else{
            right[i]=height[i];
            max = height[i];
        }
    }
 
    //calculate totoal
    for(int i=0; i<height.length; i++){
        result+= Math.min(left[i],right[i])-height[i];
    }
 
    return result;
}

13 thoughts on “LeetCode – Trapping Rain Water (Java)”

  1. = It can be solve by scanning from both sides and then get the total.
    it is not an explanation.

    here is explanation:

    =1
    lets say for indxs 0 and N it is 2 biggest elevation points!
    max1 x x x x x maxN
    solution is simple, you min( max1, maxN) multiply length of array, and minus all elevations points inside. they all smaller.

    =2 lets say it is not.

    there is bigger elevation point after max1 (left to right ), and-or bigger elevation point before maxN (from right to left) , we did reduction! calc result for found new max’s on left and right sides and repeat!!

    that is it!

    this is variation of solution finding closest bigger element for array element to left or right!


  2. class Solution {
    public:
    int trap(vector& height) {
    // maxLeft[i] = max height to the left of i
    // maxRight[i] = max height to the right of i
    vector maxLeft(height.size()), maxRight(height.size());
    if(height.size() == 0) return 0;
    maxLeft[0] = height[0];
    maxRight[height.size() - 1] = height[height.size() - 1];
    for(int i = 1, j = height.size() - 2; i = 0; i++, j--) {
    maxLeft[i] = max(maxLeft[i - 1], height[i]);
    maxRight[j] = max(maxRight[j + 1], height[j]);
    }
    int ans = 0;
    for(int i = 0; i < height.size(); i++) {
    int minFromTwoSides = min(maxLeft[i], maxRight[i]);
    ans += max(minFromTwoSides - height[i], 0);
    }
    return ans;
    }
    };

  3. My solution in Javascript (the relevant part):

    function calcLeftSideSupport(inputArray){
    let resultArray = [];
    let tempMax = 0;

    for(let i=0; i= tempMax){
    tempMax = inputArray[i];
    }
    resultArray[i] = tempMax;
    }
    return resultArray;
    }
    function calcRightSideSupport(inputArray){
    let resultArray = [];
    let tempMax = 0;

    for(let i=inputArray.length-1; i>=0;i--){
    if (inputArray[i] >= tempMax){
    tempMax = inputArray[i];
    }
    resultArray[i] = tempMax;
    }
    return resultArray;
    };

    function calcRainCapacity(originalArray, leftArray, rightArray){
    let rainCapacity = 0;
    let rainArray = [];
    for(let i=0;i<originalArray.length;i++){
    rainArray[i]= Math.min(leftArray[i],rightArray[i]) - originalArray[i];
    rainCapacity += rainArray[i];
    }
    return [rainCapacity,rainArray];
    }

    function calcMaxHeight(numberArray){
    let tempArray = numberArray.slice();
    let maxHeight = tempArray.sort(function(a, b){return b-a})[0];
    return maxHeight;
    }

  4. You can use given heights array to calculate it, firstly see my c++ solution above by using one array instead of two arrays, then you can reuse heights by start from two ends.


  5. int Water::trapping(const vector& heights) {
    if (heights.size() < 2) {
    return 0;
    }
    vector heights;

    heights.push_back(heights[0]);

    for (int i = 1; i = 0; i--) {
    int m = i == heights.size() - 1 ? heights[i] : max(heights[i], heights[i + 1]);
    heights[i] = min(heights[i], m);
    }

    int t = 0;

    for (int i = 1; i < heights.size(); i++) {
    t += min(heights[i], heights[i - 1]);
    }

    return t;
    }


  6. public class Solution {
    public int trap(int[] height) {
    if(height == null || height.length==0) return 0;
    int leftMax = 0, rightMax = 0, left = 0, max = 0;
    int right = height.length-1;
    while(left height[left] ? leftMax : height[left];
    rightMax = rightMax > height[right] ? rightMax : height[right];
    max += leftMax < rightMax ? leftMax - height[left++] : rightMax - height[right--];
    }
    return max;
    }
    }


  7. public class Solution {
    public int trap(int[] height) {
    int l = height.length;
    if(l < 3) return 0;
    int[] leftMax = new int[l];
    int[] rightMax = new int[l];
    int maxL = height[0];
    int maxR = height[l-1];
    for(int i = 0; i maxL ? height[i] : maxL;
    leftMax[i] = maxL;
    maxR = height[l-1-i] > maxR ? height[l-1-i] : maxR;
    rightMax[l-1-i] = maxR;
    }
    int waterTrapped = 0;
    for(int i = 0; i rightMax[i] ? rightMax[i] - height[i] : leftMax[i] - height[i];
    }
    return waterTrapped;
    }
    }

  8. Constant O(1) space and O(n) time.

    public class Solution {
    public int trap(int[] height) {
    if (height == null || height.length < 3)
    return 0;

    int result = 0;
    int left = 0;
    int right = height.length - 1;
    int maxLeft = 0;
    int maxRight = 0;
    int curHeight;

    while (left < right) {
    curHeight = Math.min(maxLeft, maxRight);
    if (maxLeft < maxRight) {
    result += Math.max(curHeight - height[left], 0);
    maxLeft = Math.max(height[left], maxLeft);
    left++;
    }
    else {
    result += Math.max(curHeight - height[right], 0);
    maxRight = Math.max(height[right], maxRight);
    right--;
    }
    }

    curHeight = Math.min(maxLeft, maxRight);
    result += Math.max(curHeight - height[right], 0);

    return result;
    }
    }

  9. Is it possible to do it in constant time? it’s a FB interview question. Haven’t figured out how to do it…

Leave a Comment