动态规划+双指针
class Solution:
def trap(self, height: List[int]) -> int:
# 动态规划
n = len(height)
leftMax = [height[0]] + [0] * (n-1)
for i in range(1, n):
leftMax[i] = max(leftMax[i-1], height[i])
rightMax = [0] * (n-1) + [height[-1]]
for i in range(n - 2, -1, -1):
rightMax[i] = max(rightMax[i+1], height[i])
ans = sum(min(leftMax[i], rightMax[i]) - height[i] for i in range(n))
# 双指针
left, right = 0, len(height) - 1
leftMax = rightMax = 0
ans = 0
while (left < right):
# 维护左边最高和右边最高的变量
leftMax = max(leftMax, height[left])
rightMax = max(rightMax, height[right])
if height[left] < height[right]:
# 更新左边
ans += leftMax - height[left]
left += 1
else:
# 更新右边
ans += rightMax - height[right]
right -= 1
return ans
单调栈解法
维护一个单调递减栈(存放下标),因为当遍历的元素的高度大于栈顶元素高度,说明栈顶元素的位置出现了凹槽,需要计算雨水量
三种情况:
1)遍历元素<栈顶元素:直接入栈
2)遍历元素==栈顶元素:更新下标
3)遍历元素>栈顶元素:出现凹槽,计算雨水量,注意持续维护单调递减栈
class Solution:
def trap(self, height: List[int]) -> int:
res = 0
# 维护一个单调递减栈,存下标
stack = [0]
for i in range(1, len(height)):
# 小于栈顶元素,入栈
if height[i] < height[stack[-1]]:
stack.append(i)
# 等于栈顶元素,更新下标
elif height[i] == height[stack[-1]]:
stack.pop()
stack.append(i)
# 大于栈顶元素,说明栈顶元素位置处出现凹槽,需要计算雨水量
else:
# 持续维护单调递减栈
while stack and height[i] > height[stack[-1]]:
mid = stack.pop()
if stack:
left = stack[-1]
mid_height = height[mid] # 中间高度
left_height = height[left] # 左边高度:即栈中下一个元素
right_height = height[i] # 右边高度:当前高度
res += (min(left_height, right_height) - mid_height) * (i - left - 1)
stack.append(i)
return res