42. 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!

链接: 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

posted @ 2017-04-25 10:03  panini  阅读(111)  评论(0编辑  收藏  举报