题目:
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!
链接: http://leetcode.com/problems/trapping-rain-water/
4/16/2017
BB电面准备
21ms, 77%
不是自己做出来的。思路:找到当前位置左边最大的bar和右边最大的bar,分别在2个数组中。选择其中较小的一边作为高度,宽度为1,并且减去当前bar自己的面积。
注意的问题:
1. forward, backward每一个值其实是不含跟height[i]比较的,是左边(不含自己)与右边(不含自己)
2. 第22行需要判断volume大于0,为什么?比方说[1,2,1]到中间元素时curVolume = -1,不要加到结果中去。
1 public class Solution { 2 public int trap(int[] height) { 3 if (height.length <= 2) return 0; 4 int[] forward = new int[height.length]; 5 int[] backward = new int[height.length]; 6 7 int leftBar = height[0]; 8 for (int i = 1; i < height.length; i++) { 9 forward[i] = leftBar; 10 leftBar = Math.max(height[i], leftBar); 11 } 12 int rightBar = height[height.length - 1]; 13 for (int i = height.length - 2; i >= 0; i--) { 14 backward[i] = rightBar; 15 rightBar = Math.max(height[i], rightBar); 16 } 17 18 int sumVolume = 0; 19 int curVolume; 20 for (int i = 0; i < height.length; i++) { 21 curVolume = Math.min(forward[i], backward[i]) - height[i]; 22 if (curVolume > 0) sumVolume += curVolume; 23 } 24 return sumVolume; 25 } 26 }
双指针解法, 23ms, 52%
参考:http://www.cnblogs.com/yrbbest/p/4436338.html
https://discuss.leetcode.com/topic/5125/sharing-my-simple-c-code-o-n-time-o-1-space
跟之前一种解法其实思路是大致相同的。首先判断在相反方向自己是否是短板,若是,则判断是否高于之前的最高值,若是则更新最高值,若不是则加上当前高度差。
双指针为了什么?
自己认为是为了保证更新自己方面,比如quicksort是不符合规矩的一边改变index,这里是短板的一边计算volume值。
1 public class Solution { 2 public int trap(int[] height) { 3 if (height.length <= 2) return 0; 4 int lo = 0, hi = height.length - 1; 5 int maxL = 0, maxR = 0; 6 int volume = 0; 7 8 while (lo <= hi) { 9 // find the left most index could pair with right 10 if (height[lo] <= height[hi]) { 11 // if current height less than its left max bar, it's in a basin, add volume 12 if (height[lo] < maxL) { 13 // height difference is volume 14 volume += maxL - height[lo]; 15 } else { 16 // upward, update maxL 17 maxL = height[lo]; 18 } 19 lo++; 20 } else { 21 if (height[hi] < maxR) { 22 volume += maxR - height[hi]; 23 } else { 24 maxR = height[hi]; 25 } 26 hi--; 27 } 28 } 29 return volume; 30 } 31 }
还有一个stack的做法,有时间需要研究一下
https://discuss.leetcode.com/topic/4939/a-stack-based-solution-for-reference-inspired-by-histogram
更多讨论:
https://discuss.leetcode.com/category/50/trapping-rain-water