42. 接雨水

1. 题目

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

示例 1:

img

1
2
3
输入:height = [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 个单位的雨水(蓝色部分表示雨水)。

示例 2:

1
2
输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

2. 思路

  • 初始化L数组与R数组,并初始化lMax变量与rMax变量

    • L数组: 从左往右遍历存储与左侧最大值lMax与当前值的差值

    • R数组: 从右往左遍历存储与右侧最大值rMax与当前值的差值

    • lMax变量: 当遍历生成L数组的同时,实时更新该变量为最大值

    • rMax变量: 当遍历生成R数组的同时,实时更新该变量为最大值

  • 在完成上述L数组和R数组的计算后,使用变量count遍历累加获取Math.min(L[i], R[i]) - height[i]值得到答案,如下图

image-20230730170641953

3. 代码

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) {
var l = new int[height.length];
var r = new int[height.length];

var lMax = 0;
var rMax = 0;

for (var i = 0; i < height.length; ++i) {
l[i] = Math.max(lMax, height[i]);
lMax = Math.max(lMax, height[i]);
}

for (var i = height.length - 1; i >= 0; --i) {
r[i] = Math.max(rMax, height[i]);
rMax = Math.max(rMax, height[i]);
}

var count = 0;

for (var i = 1; i < height.length; ++i) {
var depth = Math.min(l[i], r[i]);
count += depth - height[i];
}

return count;
}
}

4. 复杂度

  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

image-20230730170713210