题目描述:
给定一个数组,数组的每个元素代表一个高度,假设这个数组是一个直方图,求这个直方图能够接到多少单位的雨水。
示例:
输入:[0,1,0,2,1,0,1,3,2,1,2,1] 输出:6
解释:数组中的数字代表高度,可以看成一个直方图,其中高度为1的位置能接到1单位的雨水,高度为2的位置能接到2单位的雨水,高度为3的位置能接到3单位的雨水,因此总共能接到6单位的雨水。
思路:
这道题可以通过暴力解法、动态规划、单调栈等多种方法解决,这里介绍使用双指针的方法。
- 定义两个指针left和right,初始值分别为数组的第一个和最后一个元素的下标。
- 定义两个变量left_max和right_max,分别表示左侧最大值和右侧最大值。
- 如果height[left] < height[right],说明left处能够接到的雨水取决于left_max的值,因此更新left处的雨水量,并将left指针右移一位,更新left_max的值。
- 如果height[left] >= height[right],说明right处能够接到的雨水取决于right_max的值,因此更新right处的雨水量,并将right指针左移一位,更新right_max的值。
- 循环以上操作,直到left和right指针重合,计算出总的雨水量。
代码实现:
Java 代码实现如下:
public int trap(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int left = 0, right = height.length - 1;
int left_max = 0, right_max = 0;
int ans = 0;
while (left < right) {
if (height[left] < height[right]) {
left_max = Math.max(left_max, height[left]);
ans += left_max - height[left];
left++;
} else {
right_max = Math.max(right_max, height[right]);
ans += right_max - height[right];
right--;
}
}
return ans;
}
时间复杂度:O(n) 空间复杂度:O(1)