接雨水#
每个位置能接的雨水由左右最高墙得到:
w = max(0, min(leftmax(i), rightmax(i)) - height[i])
问题转换成,如何高效得到 leftmax(i) 和 rightmax(i)。
可以从两端向中间收缩,维护 leftMax 和 rightMax
如果 height[l] < height[r] 那么 l 的可接水上限由 leftMax 决定:
- 如果 height[l] >= leftMax: 更新 leftMax,不做任何处理,因为这个时候一定是接不到水的。
- 否则 leftMax - height[l] 就是 l 位置可接水的量,为什么是这样?这里解释下,由于 rightMax > height[r],而 height[r] > height[l],但是 height[l] < leftMax,所以 leftMax < rightMax
- 然后 l++
java 解法#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| class Solution {
public int trap(int[] height) {
if (height.length < 3) {
return 0;
}
int l = 0, r = height.length - 1;
int leftMax = 0, rightMax = 0;
int ans = 0;
while (l < r) {
if (height[l] < height[r]) {
if (height[l] >= leftMax) {
leftMax = height[l];
} else {
ans += leftMax - height[l];
}
l ++;
} else {
if (height[r] >= rightMax) {
rightMax = height[r];
} else {
ans += rightMax - height[r];
}
r --;
}
}
return ans;
}
}
|
Python 解法#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| class Solution:
def trap(self, height: List[int]) -> int:
n = len(height)
if n < 3:
return 0
l, r = 0, n - 1
left_max = right_max = 0
ans = 0
while l < r:
if height[l] < height[r]:
if height[l] >= left_max:
left_max = height[l]
else:
ans += left_max - height[l]
l += 1
else:
if height[r] >= right_max:
right_max = height[r]
else:
ans += right_max - height[r]
r -= 1
return ans
|
JS 解法#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| var trap = function(height) {
const n = height.length;
if (n < 3) return 0;
let l = 0, r = n - 1;
let leftMax = 0, rightMax = 0;
let ans = 0;
while (l < r) {
if (height[l] < height[r]) {
if (height[l] >= leftMax) {
leftMax = height[l];
} else {
ans += leftMax - height[l];
}
l ++;
} else {
if (height[r] >= rightMax) {
rightMax = height[r];
} else {
ans += rightMax - height[r];
}
r --;
}
}
return ans;
};
|
Go 解法#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| func trap(height []int) int {
n := len(height)
if n < 3 {
return 0
}
l, r := 0, n-1
leftMax, rightMax := 0, 0
ans := 0
for l < r {
if height[l] < height[r] {
if height[l] >= leftMax {
leftMax = height[l]
} else {
ans += leftMax - height[l]
}
l ++
} else {
if height[r] >= rightMax {
rightMax = height[r]
} else {
ans += rightMax - height[r]
}
r --
}
}
return ans
}
|