https://oj.leetcode.com/problems/trapping-rain-water/
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], 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!
SOLUTION 1:
从左到右扫描,计算到从左边到curr的最高的bar,从右到左扫描,计算到从右边到curr的最高的bar。
再扫描一次,把这两者的低者作为{桶}的高度,如果这个桶高于A[i]的bar,那么A[i]这个bar上头可以存储height - A[i]这么多水。把这所有的水加起来即可。
1 public class Solution { 2 public int trap(int[] A) { 3 if (A == null) { 4 return 0; 5 } 6 7 int max = 0; 8 9 int len = A.length; 10 int[] left = new int[len]; 11 int[] right = new int[len]; 12 13 // count the highest bar from the left to the current. 14 for (int i = 0; i < len; i++) { 15 left[i] = i == 0 ? A[i]: Math.max(left[i - 1], A[i]); 16 } 17 18 // count the highest bar from right to current. 19 for (int i = len - 1; i >= 0; i--) { 20 right[i] = i == len - 1 ? A[i]: Math.max(right[i + 1], A[i]); 21 } 22 23 // count the largest water which can contain. 24 for (int i = 0; i < len; i++) { 25 int height = Math.min(right[i], left[i]); 26 if (height > A[i]) { 27 max += height - A[i]; 28 } 29 } 30 31 return max; 32 } 33 }
2015.1.14 redo:
合并2个for 循环,简化计算。
1 public class Solution { 2 public int trap(int[] A) { 3 // 2:37 4 if (A == null) { 5 return 0; 6 } 7 8 int len = A.length; 9 int[] l = new int[len]; 10 int[] r = new int[len]; 11 12 for (int i = 0; i < len; i++) { 13 if (i == 0) { 14 l[i] = A[i]; 15 } else { 16 l[i] = Math.max(l[i - 1], A[i]); 17 } 18 } 19 20 int water = 0; 21 for (int i = len - 1; i >= 0; i--) { 22 if (i == len - 1) { 23 r[i] = A[i]; 24 } else { 25 // but: use Math, not max 26 r[i] = Math.max(r[i + 1], A[i]); 27 } 28 29 water += Math.min(l[i], r[i]) - A[i]; 30 } 31 32 return water; 33 } 34 }
CODE:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/array/Trap.java