问题描述
给定 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
解题思路
-
找到最高柱子: 遍历数组找到最高柱子的索引。最高柱子的高度即为能够接到的最高雨水的高度。
-
处理左侧:
- 从左到最高柱子位置遍历,维护一个左侧最高柱子的高度。
- 对于每个柱子,计算它能够接到的雨水高度:
max(左侧最高柱子高度, 当前柱子高度) - 当前柱子高度
。
-
处理右侧:
- 从右到最高柱子位置遍历,维护一个右侧最高柱子的高度。
- 对于每个柱子,计算它能够接到的雨水高度:
max(右侧最高柱子高度, 当前柱子高度) - 当前柱子高度
。
-
计算总雨水量:
- 将每个柱子能接到的雨水高度相加,即为最终结果。
代码实现
class Solution {
public int trap(int[] height) {
int n = height.length;
if (n <= 2) {
return 0; // 如果柱子数小于等于2,无法接到雨水
}
int result = 0;
int maxHeightIndex = 0;
// 找到最高柱子的索引
for (int i = 0; i < n; i++) {
if (height[i] > height[maxHeightIndex]) {
maxHeightIndex = i;
}
}
// 从左到最高柱子位置
int leftMax = 0;
for (int i = 0; i < maxHeightIndex; i++) {
leftMax = Math.max(leftMax, height[i]);
result += Math.max(0, leftMax - height[i]);
}
// 从右到最高柱子位置
int rightMax = 0;
for (int i = n - 1; i > maxHeightIndex; i--) {
rightMax = Math.max(rightMax, height[i]);
result += Math.max(0, rightMax - height[i]);
}
// 返回最终可以接到的雨水量
return result;
}
}
测试
public static void main(String[] args) {
Solution solu = new Solution();
// 示例
int[] height1 = {0,1,0,2,1,0,1,3,2,1,2,1};
int[] height2 = {4,2,0,3,2,5};
int result1 = solu.trap(height1);
int result2 = solu.trap(height2);
System.out.println(result1); // 输出:6
System.out.println(result2); // 输出:9
}