题目来源:LeetCode
理解
:给定数组,每个元素表示一个高度,求该数组对应的直方图可以存水多少?
思路
:针对每一列,计算其左边最高的高度 hleft 与其右边最高的高度 hright 之间的最小值,用该值减去当前列的高度,即为当前列可以存放的水量。
Python
:
lens = len(height)
res = 0
for i in range(1, lens - 1):
# 设右边无穷高,计算当前列左边最大高度和当前列可以存放的水量
left = height[:i].copy()
leftMax = max(left) - height[i]
# 设左边无穷高,计算当前列右边最大高度和当前列可以存放的水量
right = height[i:lens].copy()
rightMax = max(right) - height[i]
# 若两边均小于0,则当前列过高,无法存水
# 反之,根据木桶效应,选取可存放的水量中的较小数值
if min(leftMax, rightMax) < 0:
res += 0
else:
res += min(leftMax, rightMax)
return res
执行结果
:
优化
:上段代码中,计算左右两边的max时,之前已经比较过的列高会再次进行计算,因此采用两个单串dp进行优化。
lens = len(height)
leftmax = [0 for _ in range(lens+2)]
rightmax = [0 for _ in range(lens+2)]
# 先遍历一次,计算左右最大值
for i in range(lens):
leftmax[i] = max(leftmax[i-1], height[i])
rightmax[lens-i-1] = max(rightmax[lens-i], height[lens-i-1])
res = 0
# 计算结果
for i in range(lens):
res += max(0,min(leftmax[i],rightmax[i])-height[i])
return res
执行结果
: