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;
    }
    

      

      

  • 相关阅读:
    MongoDB Master-Slave cluster with authentication setup
    Linux Shell Scripting Cookbook 读书笔记 5
    Linux Shell Scripting Cookbook 读书笔记 4
    Linux Shell Scripting Cookbook 读书笔记 3
    Linux Shell Scripting Cookbook 读书笔记 2
    Citrix架构
    Jenkins Kubernetes Slave 调度效率优化小记
    <漫谈ElasticSearch>关于ES性能调优几件必须知道的事
    【反思】一个价值两天的BUG,无论工作还是学习C语言的朋友都看看吧!
    <再看TCP/IP第一卷>TCP/IP协议族中的最压轴戏----TCP协议及细节
  • 原文地址:https://www.cnblogs.com/apanda009/p/7115984.html
Copyright © 2011-2022 走看看