接雨水
题目描述:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [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
解题思路:
-
我们实际是需要找到一个空位,并且保证空位左右两边的高度不能低于它,即存在两种情况,我们从左向右遍历,找到右挡板比左边高的情况;然后从右向左遍历,找到左挡板比右边高的情况
-
以从左向右为例,创建左挡板位置字典
temp_max = [id, i]
,其中id
表示位置,i
表示当前位置的高度。对目标数组进行遍历找到右挡板,要满足(1)右挡板比左挡板高->i > temp_max[1]
;(2)右挡板应该在左挡板右边两个位置,这样才可能出现空格 -
如果上述条件都满足,就用两个挡板之间的距离乘以左挡板的高度,减去左挡板到右挡板之间位置的高度
(id - temp_max[0] - 1) * temp_max[1] - sum(height[temp_max[0] + 1:id])
-
同理,可以从右向左遍历,找到左挡板比右挡板高的情况,然后将两种情况的结果相加,得到结论
Python源码:
from typing import List
class Solution:
def trap(self, height: List[int]) -> int:
if not height: # 边界检查
return 0
result = 0
temp_max = None # 首先从左遍历到右边
for id, i in enumerate(height):
if temp_max is None:
temp_max = [id, i]
else:
if i > temp_max[1]:
if id - temp_max[0] != 1:
result += (id - temp_max[0] - 1) * temp_max[1] - sum(height[temp_max[0] + 1:id])
temp_max = [id, i]
temp_max = None # 然后从右到左遍历
for j in range(len(height) - 1, -1, -1):
if temp_max is None:
temp_max = [j, height[j]]
else:
if height[j] >= temp_max[1]:
if temp_max[0] - j != 1:
result += (temp_max[0] - 1 - j) * temp_max[1] - sum(height[j + 1: temp_max[0]])
temp_max = [j, height[j]]
return result
欢迎关注我的github:https://github.com/UESTCYangHR