2014年11月27日星期四

[Leetcode] Trapping Rain Water

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.


The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

On any given position, the water it could hold is determined by the minimum height of the highest elevation on its both side. For example, [1, 0, 2, 3], the water could be hold at '0' is determined by the highest elevation on its left which is 1 and highest elevation on its right which is 3. We need to choose the minimum of this two value, given 1.


    public int trap(int[] A) {
        int n = A.length;
        if(n == 0)
            return 0; // corner case
        int[] left = new int[n]; // highest on left
        int[] right = new int[n]; // highest on right
        left[0] = A[0];
        int ma = A[0];
        for(int i = 1; i < n; i++) {
            ma = Math.max(ma, A[i]);
            left[i] = ma;
        }
        right[n-1] = A[n-1];
        ma = A[n-1];
        for(int i = n-2; i >= 0; i--) {
            ma = Math.max(ma, A[i]);
            right[i] = ma;
        }
        int res = 0;
        for(int i = 0; i < n; i++) {
            res = res + Math.min(left[i], right[i]) - A[i];
        }
        return res;
    }

The time complexity is O(n) and the space complexity is O(n).
A follow of this problem is given that at a point where the elevation is zero, it is leaking water and could not hold any water there. In this case, we need just to modify ma to 0 in this case. Which give the following code.
 /* A kind of follow up of Trapping Raining Water,
  * where the elevation with 0 is leaking water and
  * could not hold water
  */
    public static int trap(int[] A) {
        int n = A.length;
        if(n == 0)
            return 0; // corner case
        int[] left = new int[n]; // highest on left
        int[] right = new int[n]; // highest on right
        left[0] = A[0];
        int ma = A[0];
        for(int i = 1; i < n; i++) {
            ma = Math.max(ma, A[i]);
            ma = A[i] == 0 ? 0 : ma;
            left[i] = ma;
        }
        right[n-1] = A[n-1];
        ma = A[n-1];
        for(int i = n-2; i >= 0; i--) {
            ma = Math.max(ma, A[i]);
            ma = A[i] == 0 ? 0 : ma;
            right[i] = ma;
        }
        int res = 0;
        for(int i = 0; i < n; i++) {
            res = res + Math.min(left[i], right[i]) - A[i];
        }
        return res;
    }

没有评论:

发表评论