题目:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trapping-rain-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
个人思路:
应该是根据左右侧最低高度求解。。。
官方答案推荐:
①按行求,会超时
②按列求,即求没列的左侧最高和右侧最高
③栈,按照括号匹配的规则,不断进栈出栈
④双指针,以前后两个指针不断求出左侧最高和右侧最高
python代码:
class Solution:
#按第i列有几个蓝色小正方形进行计算
def trap(self, height: List[int]) -> int:
#采用类似快排的双指针法,索引i在left和right间来回切换
#i=0时必定存不到水
left = 1
#i=length-1也必定存不到水
right = len(height) - 2
#至少3列
if right < 1:
return 0
#由图可知,第i列的存水由min(左侧最高点,右侧最高点)决定,即木桶原理
left_max = height[0]
right_max = height[len(height) - 1]
result = 0
while left <= right:
#指针在左侧时,left_max必定正确,而right_max和当前索引left之间有不确定值,不一定是最大的
if left_max <= right_max:
#先求result再更新,保证每次判断时left_max都是最新出炉的
if left_max > height[left]:
result += left_max - height[left]
left_max = max(left_max,height[left])
left += 1
#同理,右侧时right_max必定正确
else:
if right_max > height[right]:
result += right_max - height[right]
right_max = max(right_max,height[right])
right -= 1
return result
反思:
重点是从左看和从右看可判断出的左右侧最大值比较难想,最傻的方案自然是加一个从左到右循环记录最大值。
记录和更新顺序也别搞错了。。。