算法很簡單,核心思想是:對某個值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 }