@@ -11,20 +11,33 @@ public int trap(int[] height) {
11
11
return trap4 (height );
12
12
}
13
13
14
+ /**
15
+ * <pre>
16
+ * 对于每个柱子,找到其左右两边最高的柱子,该柱子能容纳的面积就是min(max_left,max_right) - height。所以,
17
+ * 1. 从左往右扫描一遍,对于每个柱子,求取左边最大值;
18
+ * 2. 从右往左扫描一遍,对于每个柱子,求最大右值;
19
+ * 3. 再扫描一遍,把每个柱子的面积并累加。
20
+ * </pre>
21
+ *
22
+ * @param height
23
+ * @return
24
+ */
14
25
public int trap1 (int [] height ) {
15
26
int ans = 0 ;
16
27
int size = height .length ;
17
28
for (int i = 1 ; i < size - 1 ; i ++) {
18
29
int maxLeft = 0 ;
19
30
int maxRight = 0 ;
20
- for (int j = i ; j >= 0 ; j --) { //Search the left part for max bar size
31
+ // 找此柱左边最高的柱子
32
+ for (int j = i - 1 ; j >= 0 ; j --) {
21
33
maxLeft = Math .max (maxLeft , height [j ]);
22
34
}
23
- for (int j = i ; j < size ; j ++) { //Search the right part for max bar size
35
+ // 找此柱子右边最高的柱子
36
+ for (int j = i + 2 ; j < size ; j ++) {
24
37
maxRight = Math .max (maxRight , height [j ]);
25
38
}
26
39
27
- // TODO 原理是什么?
40
+ // Math.min(maxLeft, maxRight) - height[i] 此柱子可以容纳的水
28
41
ans += Math .min (maxLeft , maxRight ) - height [i ];
29
42
}
30
43
return ans ;
@@ -39,15 +52,13 @@ int trap2(int[] height) {
39
52
int [] leftMax = new int [size ];
40
53
int [] rightMax = new int [size ];
41
54
42
- leftMax [0 ] = height [0 ];
43
- for (int i = 1 ; i < size ; i ++) {
55
+
56
+ // 对于每个柱子求左右最大值,并保存起来
57
+ for (int i = 1 ; i < size - 1 ; i ++) {
44
58
leftMax [i ] = Math .max (height [i ], leftMax [i - 1 ]);
59
+ rightMax [size - i - 1 ] = Math .max (height [size - i ], rightMax [size - i ]);
45
60
}
46
61
47
- rightMax [size - 1 ] = height [size - 1 ];
48
- for (int i = size - 2 ; i >= 0 ; i --) {
49
- rightMax [i ] = Math .max (height [i ], rightMax [i + 1 ]);
50
- }
51
62
52
63
for (int i = 1 ; i < size - 1 ; i ++) {
53
64
ans += Math .min (leftMax [i ], rightMax [i ]) - height [i ];
0 commit comments