算法很简单,核心思想是:对某个值A[i]来说,能trapped的最多的water取决于在i之前最高的值leftMostHeight[i]和在i右边的最高的值rightMostHeight[i]。(均不包含自身)。如果min(left,right) > A[i],那么在i这个位置上能trapped的water就是min(left,right) – A[i]。
有了这个想法就好办了,第一遍从左到右计算数组leftMostHeight,第二遍从右到左计算rightMostHeight,在第二遍的同时就可以计算出i位置的结果了,而且并不需要开空间来存放rightMostHeight数组。
时间复杂度是O(n),只扫了两遍。
1 public class TrappingRainWater {
2 public int trap(int A[], int n) {
3 if (n <= 2)
4 return 0;
5
6 int[] lmh = new int[n];
7 lmh[0] = 0;
8 int maxh = A[0];
9 for (int i = 1; i < n; ++i) {
10 lmh[i] = maxh;
11 if (maxh < A[i])
12 maxh = A[i];
13 }
14 int trapped = 0;
15 maxh = A[n - 1];
16 for (int i = n - 2; i > 0; --i) {
17 int left = lmh[i];
18 int right = maxh;
19 int container = Math.min(left, right);
20 if (container > A[i]) {
21 trapped += container - A[i];
22 }
23 if (maxh < A[i])
24 maxh = A[i];
25 }
26 return trapped;
27 }
28 }