LeetCode - Trap Rain Water
来源:互联网 发布:中南大学怎么样 知乎 编辑:程序博客网 时间:2024/06/03 21:50
这道题思维很巧妙,不管是two pointer方法,还是stack方法,能想出来的都太厉害了!
首先,two pointer两遍扫描,对于每个位置来说,找到它左右最高的bar,那么当前位置能储存的水量就是两边最高bar较小那个的值-自己的值,代码如下:
public int trap(int[] A){ if(A==null ||A.length==0) return 0; int trap = 0; int[] lmax = new int[A.length]; int[] rmax = new int[A.length]; lmax[0]=0; for(int i=1; i<A.length; i++){ lmax[i] = Math.max(A[i-1],lmax[i-1]); } rmax[A.length-1]=0; for(int i=A.length-2; i>=0; i--){ rmax[i] = Math.max(rmax[i+1],A[i+1]); } for(int i=0; i<A.length; i++){ int tmp = Math.min(lmax[i],rmax[i])-A[i]; if(tmp>0) trap+=tmp; } return trap; }
另外一种DP只需要一遍扫描,即一个指针从左往右扫,一个指针从右往左扫,那边值小哪边就是装水的限制,所以值小的那边继续扫,直到扫到比初始的限制值大为止,扫的过程中记录每个位置能装水的数量,直到两个指针相遇:
public int trap(int[] A){ if(A==null ||A.length==0) return 0; int trap = 0; int start = 0; int end = A.length-1; while(start<end){ if(A[start]<=A[end]){ int tmp = A[start]; while(A[start]<=tmp){ trap+= tmp-A[start]; start++; if(start==end) return trap; } } else if(A[start]>A[end]){ int tmp = A[end]; while(A[end]<=tmp){ trap+= tmp-A[end]; end--; if(start==end) return trap; } } } return trap; }
刚看到这道题的时候,就觉得应该用stack,但想了半天也没想出来正确的计算方法,还是看的答案,简洁的代码和解释见:
http://n00tc0d3r.blogspot.com/2013/06/trapping-rain-water.html
下面是我重写的代码:
public int trap(int[] A) { Stack<Integer> bar = new Stack<Integer>(); int trap = 0; for(int i=0; i<A.length; i++){ if(bar.size()==0) bar.push(i); else{ if(A[i]<=A[bar.peek()]){ bar.push(i); } else{ while(bar.size()!=0 && A[bar.peek()]<A[i]){ int tmp = bar.pop(); if(bar.empty()) break; trap += (Math.min(A[i],A[bar.peek()])-A[tmp])*(i-bar.peek()-1); } bar.push(i); } } } return trap; }
没有原代码简洁,不过好歹自己按思路写一遍,更能记得住。
总结:这种和两边值有关的题都可以用两边扫描的方法,另外用stack也可以存储左边的值,等找到合适的右边值后再回到stack中看左边的值。
0 0
- LeetCode - Trap Rain Water
- LeetCode -- Trap Water Rain
- [leetcode]Trap water解法
- 【Leetcode】Traping Rain Water (Water)
- LeetCode: Trapping Rain Water
- LeetCode : Trapping Rain Water
- [LeetCode] Trapping Rain Water
- [Leetcode] Trapping Rain Water
- [Leetcode] Trapping Rain Water
- [LeetCode]Trapping Rain Water
- LeetCode-Trapping Rain Water
- [leetcode] Trapping Rain Water
- [LeetCode] Trapping rain water
- Leetcode: Trapping Rain Water
- Leetcode:Trapping Rain Water
- [LeetCode] Trapping Rain Water
- <Leetcode>Trapping Rain Water
- Leetcode Trapping Rain Water
- NOIP2002 均分纸牌
- Sicily 2611. Da Vinci Code
- 【转】Linux_lsof追踪进程或用户恢复删除文件
- Android开发-四大组件之服务、广播
- C++11中bind的用法
- LeetCode - Trap Rain Water
- Sicily 2610/1897. Chutter and Ladder
- 编译Sanbox
- ARM裸机编程系列---UART
- Sicily 2609/1954. Bracket Expression
- zendstudio 12 配置 xdebug 开发 thinkphp
- Sicily 1898. Tree
- Swift语法基础:17 - Swift的For循环, While, Do-While, If, Switch
- poj 3667 hotel