接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

 

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

两次遍历。第一次从左到右遍历,找到从左到本点的最大值,记录进help数组;第二次,从右往左遍历,找到从右到本点间最大的值,两个值取小替换掉原help数组处的值。累加求每个点可以存储的雨量。

 1 public class T42_GetRain {
 2     public int trap(int[] height) {
 3         if (height == null || height.length < 3) {
 4             return 0;
 5         }
 6         int[] help = new int[height.length];
 7         int leftMax = height[0];
 8         int rightMax = height[height.length - 1];
 9         for (int i = 0; i < height.length; i++) {
10             help[i] = Math.max(leftMax, height[i]);
11             leftMax = help[i];
12         }
13         int res = 0;
14         for (int i = height.length - 1; i >= 0 ; i--) {
15             rightMax = Math.max(height[i], rightMax);
16             help[i] = Math.min(rightMax, help[i]);
17             res += help[i] - height[i];
18         }
19         return res;
20     }
21 }

 方法二:双指针

 1 class Solution {
 2     public int trap(int[] height) {
 3         if (height == null || height.length < 3) {
 4             return 0;
 5         }
 6         //双指针
 7         int l = 0, r = height.length - 1;
 8         int leftMax = height[0],rightMax = height[height.length - 1];
 9         int res = 0;
10         while (l < r) {
11             if (leftMax < rightMax) {
12                 if (leftMax < height[l]) {
13                     leftMax = height[l];
14                 } else {
15                     res += leftMax - height[l];
16                     l++;
17                 }
18             } else {
19                 if (rightMax < height[r]) {
20                     rightMax = height[r];
21                 } else {
22                     res += rightMax - height[r];
23                     r--;
24                 }
25             }
26         }
27         return res;
28     }
29 }
一回生,二回熟
原文地址:https://www.cnblogs.com/zzytxl/p/12432213.html