【LeetCode42】接雨水
题目描述
给定 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
解题思路
这是一道hard级别的题,博主于大一刚接触算法时候就做过这个题了。
这个题常规的思路应当是动态规划:通过对左右都进行状态转移方程的计算来得出左右高度的最大值。然后又根据我们熟知的“短板效应”,通过取左右高度最大值中最小者得出可以容纳雨水的高度,即一共有两个状态转移方程:
d
p
L
e
f
t
[
i
]
=
m
a
x
(
d
p
L
e
f
t
[
i
−
1
]
,
h
e
i
g
h
t
[
i
]
)
dpLeft[i]=max(dpLeft[i-1],height[i])
dpLeft[i]=max(dpLeft[i−1],height[i])
和
d
p
R
i
g
h
t
[
i
]
=
m
a
x
(
d
p
R
i
g
h
t
[
i
−
1
]
,
h
e
i
g
h
t
[
−
i
−
1
]
)
dpRight[i]=max(dpRight[i-1],height[-i-1])
dpRight[i]=max(dpRight[i−1],height[−i−1])
上式中下标有负数是因为实际上右最大应该是通过从右向左逆序遍历得到的
代码
class Solution:
def trap(self, height: List[int]) -> int:
# 解题关键在于计算有效块
ans=0
h_left=0
h_right=0
for i in range(len(height)):
h_left=max(h_left,height[i])
h_right=max(h_right,height[-i-1]) # 倒序找
# ans实质上是计算有效块
ans += h_left+h_right-height[i]
# 最后的接水面积就是每个有效块乘高度
return ans-len(height)*h_left #减去柱子