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.

直接做法

从左边往右边扫描,记录左边的最高值, 从右边往左扫描,记录右边的最大值 再次扫描,去某个点左边与右边的最低值,如果该值大于当前bar的高度,那么这个bar顶上就能储存水

public class Solution {
    public int trap(int[] A) {
        if (A == null) {
            return 0;
        }

        int max = 0;

        int len = A.length;
        int[] left = new int[len];
        int[] right = new int[len];

        // count the highest bar from the left to the current.
        for (int i = 0; i < len; i++) {
            left[i] = i == 0 ? A[i]: Math.max(left[i - 1], A[i]);
        }

        // count the highest bar from right to current.
        for (int i = len - 1; i >= 0; i--) {
            right[i] = i == len - 1 ? A[i]: Math.max(right[i + 1], A[i]);
        }

        // count the largest water which can contain.
        for (int i = 0; i < len; i++) {
            int height = Math.min(right[i], left[i]);
            if (height > A[i]) {
                max += height - A[i];
            }
        }

        return max;
    }
}

2019 递减stack

class Solution {
    public int trap(int[] height) {
        if (height == null || height.length == 0) return 0;
        Stack<Integer> stack = new Stack<>();
        int res = 0;
        for (int i = 0; i < height.length; i++) {
            while(!stack.isEmpty() && height[stack.peek()] < height[i]) {
                int right = height[i];
                int cur = stack.pop();
                int left = stack.isEmpty() ? height[cur]: height[stack.peek()];
                int diff = Math.min(right, left);
                int leftIndex = stack.isEmpty() ? cur : stack.peek();
                int width = i - leftIndex - 1;
                res += width * (diff - height[cur]);
            }
            stack.push(i);
        }
        return res;
    }
}

public class Solution {
    /**
     * @param heights: an array of integers
     * @return: a integer
     */
    public int trap(int[] heights) {
        if(heights == null || heights.length == 0) return 0;
        int start = 0;
        int end = heights.length - 1;
        int leftHeight = heights[start];
        int righHeight = heights[end];
        int res = 0;
        while(start < end){
            if(heights[start] < heights[end]){
                start++;
                if(heights[start] < leftHeight){
                    res = res + leftHeight - heights[start];
                    continue;
                }else{
                    leftHeight = heights[start];
                }
            }else{
                end--;
                if(heights[end] < righHeight){
                    res = res + righHeight - heights[end];
                    continue;
                }else{
                    righHeight = heights[end];
                }

            }
        }
        return res;
    }
}

自己的想法:先找出看两遍那边最小,然后从这边开始如果比开始变小的话,就可以一直算,知道拿刀一边和起始边一样了,那么要重新开始新一轮的比较了

 public int trap(int[] heights) {

     if(heights == null || heights.length == 0) return 0;

     int start = 0;

     int end = heights.length - 1;

     int leftHeight = heights[start];

     int righHeight = heights[end];

     int res = 0;

     while(start < end){

         if(heights[start] < heights[end]){

             leftHeight = heights[start];

             start++;        

                while(heights[start] < leftHeight && start < end){

                     res = res + leftHeight - heights[start];

                     start++;

                 }



         }else{

             righHeight = heights[end];

                end--;

             while(heights[end] < righHeight && start < end){

                 res = res + righHeight - heights[end];

                  end--;

             }

         }

         }

         return res;

 }

results matching ""

    No results matching ""