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

输入: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:
输入:height = [4,2,0,3,2,5]
输出:9
题解:
这题我选择用前后缀分解法,更容易理解
class Solution {
public int trap(int[] height) {
// 将柱子及其上方的水一起看作桶
int n = height.length;
int[] preMax = new int[n];// preMax[i] 表示从 height[0] 到 height[i] 的最大值,前缀
preMax[0] = height[0];// 从左往右,第一个柱的左边是height[0]的值
for (int i = 1; i < n; i++) {
preMax[i] = Math.max(preMax[i - 1], height[i]);// 左边柱子的前缀最大值和当前柱子比,谁高就更新为新当前柱子的前缀,之前的0 ~ i-1则不变
}
int[] sufMax = new int[n]; // sufMax[i] 表示从 height[i] 到 height[n-1] 的最大值,后缀
sufMax[n - 1] = height[n - 1];//从右往左,最后一个柱子的后缀即是初始最高后缀
for (int i = n - 2; i >= 0; i--) {
sufMax[i] = Math.max(sufMax[i + 1], height[i]);//仍然不断更新后缀,谁高就更新为当前i柱子的后缀
}
int ans = 0; // 初始化结果为0
for (int i = 0; i < n; i++) {
ans += Math.min(preMax[i], sufMax[i]) - height[i]; // 累加每个水桶能接多少水
}
return ans; // 前缀和后缀中谁最小就表示当前第i个桶能装多少水
}
}
具体讲解视频请看【基础算法精讲 02】
