[leetcode] 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], return6.
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!
https://oj.leetcode.com/problems/trapping-rain-water/
思 路1:对某个值A[i]来说,能装的最多的水取决于在i之前最高的值leftMaxt[i]和在i右边的最高的rightMax[i],容水量即 min(left,right) – A[i]。:为了计算高度,第一遍从左到右计算数组leftMaxt,第二遍从右到左计算rightMax。时空复杂度都是O(n)。
思路2:改进思路1,可以用常量空间搞定。具体思路,先找到最高的bar,然后总两边向中间计算,边计算边更新curHeight。
具体可参考 这里
思路1:
public class Solution { public int trap(int[] A) { if (A == null || A.length < 3) return 0; int n = A.length; int[] leftMax = new int[n]; int[] rightMax = new int[n]; int i; int max = A[0]; for (i = 1; i < n - 1; i++) { leftMax[i] = max; if (A[i] > max) max = A[i]; } max = A[n - 1]; for (i = n - 2; i > 0; i--) { rightMax[i] = max; if (A[i] > max) max = A[i]; } int count = 0; for (i = 1; i < n - 1; i++) { int min = leftMax[i] < rightMax[i] ? leftMax[i] : rightMax[i]; if (min > A[i]) count += min - A[i]; } return count; } public static void main(String[] args) { System.out.println(new Solution().trap(new int[] { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 })); } }
第三遍
思路二:
public class Solution { public int trap(int[] A) { if (A == null || A.length < 3) return 0; int n = A.length; int count=0; int midIdx = 0; int highest=A[0]; for(int i=0;i<n;i++){ if(A[i]>highest){ midIdx=i; highest=A[i]; } } int curHighest=0; for(int i=0;i<midIdx;i++){ if(A[i]<curHighest){ count+=curHighest-A[i]; }else{ curHighest=A[i]; } } curHighest=0; for(int i=n-1;i>midIdx;i--){ if(A[i]<curHighest){ count+=curHighest-A[i]; }else{ curHighest=A[i]; } } return count; } }
参考:
http://fisherlei.blogspot.com/2013/01/leetcode-trapping-rain-water.html
http://www.cnblogs.com/lichen782/p/Leetcode_Trapping_Rain_Water.html