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

      

      

  • 相关阅读:
    jquery $(document).ready() 与window.onload的区别
    【Ionic+AngularJS 开发】之『个人日常管理』App(二)
    【Ionic+AngularJS 开发】之『个人日常管理』App(一)
    移动App服务端架构设计
    jQuery 事件用法详解
    CSS实现的几款不错的菜单栏
    css清除浮动的方法总结
    常见浏览器的兼容问题
    推荐两个界面原型设计工具--GUIDesignStudio 和 Mockups For Desktop
    如何用js获取浏览器URL中查询字符串的参数
  • 原文地址:https://www.cnblogs.com/apanda009/p/7115984.html
Copyright © 2011-2022 走看看