zoukankan      html  css  js  c++  java
  • 42. Trapping Rain Water

    https://leetcode.com/problems/trapping-rain-water/#/solutions

    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!

     Fb: O(1)space

    这种方法是基于动态规划的,基本思路就是维护一个长度为n的数组,进行两次扫描,一次从左往右,一次从右往左。第一次扫描的时候维护对于每一个bar左边最大的高度是多少,存入数组对应元素中,第二次扫描的时候维护右边最大的高度,并且比较将左边和右边小的最大高度(我们成为瓶颈)存入数组对应元素中。这样两遍扫描之后就可以得到每一个bar能承受的最大水量,从而累加得出结果。这个方法只需要两次扫描,所以时间复杂度是O(2*n)=O(n)。空间上需要一个长度为n的数组,复杂度是O(n)。代码如下:

    常规做法:

    public int trap(int[] height) {
            int[] A = height;
            if(A==null || A.length==0)  
            return 0;  
            int max = 0;  
            int res = 0;  
            int[] container = new int[A.length];  
            for(int i=0;i<A.length;i++) {  
            
                max = Math.max(max,A[i]); 
                container[i]=max;  
            }  
            max = 0;  
            for(int i=A.length-1;i>=0;i--) {  
                max = Math.max(max,A[i]); 
                container[i] = Math.min(max,container[i]);  
             
                res += container[i]-A[i]>0?container[i]-A[i]:0;  
            }      
            return res;       
        }
    

      

    Here is my idea: instead of calculating area by height*width, we can think it in a cumulative way. In other words, sum water amount of each bin(width=1).
    Search from left to right and maintain a max height of left and right separately, which is like a one-side wall of partial container. Fix the higher one and flow water from the lower part. For example, if current height of left is lower, we fill water in the left bin. Until left meets right, we filled the whole container.

     左右指针、最大值维护、正序、逆序

    public int trap(int[] A){
        int a=0;
        int b=A.length-1;
        int max=0;
        int leftmax=0;
        int rightmax=0;
        while(a<=b){
            leftmax=Math.max(leftmax,A[a]);
            rightmax=Math.max(rightmax,A[b]);
            if(leftmax<rightmax){
                max+=(leftmax-A[a]);       // leftmax is smaller than rightmax, so the (leftmax-A[a]) water can be stored
                a++;
            }
            else{
                max+=(rightmax-A[b]);
                b--;
            }
        }
        return max;
    }
    

      

      

  • 相关阅读:
    cocoapods的安装与使用
    HBase源代码分析之HRegion上MemStore的flsuh流程(二)
    everything of people’s life can changed in their twenties
    java 操作流的步骤
    java 流
    java 文件过滤器 java.io.FilenameFilter
    java 递归(Recursion)
    java IO的概述和File方法
    java 泛型的嵌套(map例子)
    java 泛型接口和方法
  • 原文地址:https://www.cnblogs.com/apanda009/p/7115984.html
Copyright © 2011-2022 走看看