题目
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
解题思路
对于每一个节点, 找到左右两侧比当前值大的值, 然后用较小的值减去当前值, 累计求和即可
代码
class Solution {
public int trap(int[] height) {
int sum = 0;
int leftIndex = -1, rightIndex = -1;
for (int n = 0; n < height.length; n++) {
// 先根据之前的左右index进行判断, 提升效率
if (leftIndex > -1 && height[n] >= height[leftIndex]) { // 左侧无最大值
leftIndex = n; // 将当前值标记为左侧最大
continue;
}
if (n >= rightIndex) { // 右侧最大值需重新查找
rightIndex = -1;
}
// 如果左右节点没有确定, 循环查找
if (leftIndex < 0) {
for (int i = 0; i < n; i++) {
if (height[i] > height[n] && (leftIndex < 0 || height[leftIndex] < height[i])) {
leftIndex = i;
}
}
}
if (rightIndex < 0) {
for (int i = n + 1; i < height.length; i++) {
if (height[i] > height[n] && (rightIndex < 0 || height[rightIndex] < height[i])) {
rightIndex = i;
}
}
}
if (leftIndex < 0 || rightIndex < 0) {
continue;
}
// 取最小值减去当前值, 则为当前值的雨水体积
sum += Math.min(height[leftIndex], height[rightIndex]) - height[n];
}
return sum;
}
}