接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
感谢 Marcos 贡献此图。
示例:
1 | 输入: [0,1,0,2,1,0,1,3,2,1,2,1] |
思路
思路一:
结合数据和图,可以看出能够存积水的位置 i ,始终满足条件:
- height[i] < height[i-n]
- height[i] < height[i+m]
其中 m,n 均大于 0,同时判定两个条件会很麻烦,我们试着先找出所有高度中最高的,以这个最高的将这个高度数组分为左右两边,然后依次从 left 遍历到最高的,从 right 遍历到最高的,遍历过程中,只需要找出局部最高 part_max,
局部最高与其余高度值的差值和即为积水和
以给的例子为例,[0,1,0,2,1,0,1,3,2,1,2,1]:
- max_height = 3. 所在索引为 7
- 以左边为例,从左到最高的数组为 [0,1,0,2,1,0,1], 对于的局部最高的数组为 [0,1,1,2,2,2,2]
- 高度差依次为:[0,0,1,0,1,2,1]
- 则左边积水和为 5
- 同理可求右边为 1
- 则最终结果为 6
思路二:
双指针:假设数组 height, 长度为 n, left_max = right_max = 0, 面积为 area = 0 ,两个指针left,right 初始分别位于 0, n - 1 的位置
- height[left] < height[right], 有解法一中可以知道,这个时候只要找到 left_max > height[left] 就可以积水了,所以有:
1. 如果 height[left] > left_max: left_max = height[left] 2. 否则 area += left_max - height[left] 3. left += 1
- height[left] >height[right]:
- 如果 height[right] > right_max: right_max = height[right]
- 否则 area += right_max - height[right]
- right -= 1
解法
解法一:
1 | class Solution: |
解法二
1 | class Solution: |