42. 接雨水
思路
按照这个方向来计算雨水

还是采用单调栈的方法求解
只有凹下去的地方才能接水 也就是:中间低,左右两边高,才能存水。
单调栈怎么用?
-
栈存下标 ,保持栈内高度单调递减
-
遇到一个比栈顶高的柱子 → 说明形成凹槽,可以接水!
-
弹出栈顶,这个位置就是底部
-
新栈顶 = 左边界 ,当前元素 = 右边界
-
接水量 = 宽度 × (左右边界较小值 - 底部高度)
公式
雨水宽度 = 当前下标 - 新栈顶下标 - 1
高度 = min(左高, 右高) - 底部高度
总雨水量 += 宽度 × 高度

这里画了一次,栈里面存的是下标。30比10大,10的下标3弹出,下标2是新的栈顶元素
然后右边是计算公式伪代码,h,w计算公式可以直接看下面的提交,stack[-1]可能好理解一些
提交
python
class Solution:
def trap(self, height: List[int]) -> int:
stack = [] # 存下标,保持高度递减
res = 0
n = len(height)
for i in range(n):
# 当前高度 > 栈顶高度 → 可以接水
while stack and height[i] > height[stack[-1]]:
# 凹槽底部
bottom = stack.pop()
if not stack:
break
# 计算宽和高
w = i - stack[-1] - 1
h = min(height[i], height[stack[-1]]) - height[bottom]
res += w * h
stack.append(i)
return res
84. 柱状图中最大的矩形
题目链接84. 柱状图中最大的矩形 - 力扣(LeetCode)
思路
跟上题差不多,只是递增
找到这个柱子,左边第一个比他小的,右边第一个比他小的
宽就是这个柱子可以拓展的宽度
高就是这个柱子自己的高度

提交
python
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
stack = [] # 存下标,高度递增
max_area = 0
n = len(heights)
for i in range(n):
# 当前高度 < 栈顶高度 → 栈顶找到右边界
while stack and heights[i] < heights[stack[-1]]:
# 弹出:作为矩形高度
h_idx = stack.pop()
h = heights[h_idx]
# 左边界:栈空则为 -1,否则为新栈顶
left = stack[-1] if stack else -1
# 宽度
w = i - left - 1
# 面积
max_area = max(max_area, h * w)
stack.append(i)
# 处理栈中剩余元素(右边界 = n)
while stack:
h_idx = stack.pop()
h = heights[h_idx]
left = stack[-1] if stack else -1
w = n - left - 1
max_area = max(max_area, h * w)
return max_area