力扣 42. 接雨水

题目说明

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

  • 提示:
    • n == height.length
    • 0 <= n <= 3 * 10^4
    • 0 <= height[i] <= 10^5

示例

示例 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

笔者理解

此题是一道数组算法问题,在力扣题库中被定义为困难题。

解法

当笔者阅读完此题后,每个柱子的蓄水量与 其左边和右边最大值中的较小值 与当前柱子的差值有关,,让我们来看看具体如何实现的吧。

实现

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
29
30
31
32
class Solution {
/*
* 数组
* 动态规划
*/
public int trap(int[] height) {
int result = 0;
int n = height.length;

int[] left = new int[n];
int[] right = new int [n];

// 左边元素的最大值
left[0] = height[0];
// 右边元素的最大值
right[n - 1] = height[n - 1];

for (int i = 1; i < n; i++) {
left[i] = Math.max(left[i - 1], height[i]);
}
for (int i = n - 2; i >= 0; i--) {
right[i] = Math.max(right[i + 1], height[i]);
}

// 每一格能蓄的水等于 左右两端最大值中的较小值 减去当前格子高度
for (int i = 1; i < n - 1; i++) {
result += (Math.min(left[i], right[i]) - height[i]);
}

return result;
}
}

时间和空间效率还行,可见此解法还比较适合此题。

image-20210909165651154

总结

本题是今天的一题,难度是为困难,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。