代码随想录算法训练营第51天 | 单调栈2:接雨水问题、最大矩形问题
42.接雨水
https://leetcode.cn/problems/trapping-rain-water/
代码随想录
https://programmercarl.com/0042.接雨水.html#思路
84.柱状图中最大的矩形
https://leetcode.cn/problems/largest-rectangle-in-histogram/description/
代码随想录
https://programmercarl.com/0084.柱状图中最大的矩形.html#算法公开课
总结
抽象一下就是找凸型数据和凹型数据
42. 接雨水
题解
-
目标:找两侧比其高的元素
-
双指针:
- 从两侧遍历:找到两侧开始最高的点:该点的雨水 = min(right[i],left[i])-height[i]
-
单调栈:
- 找到比两侧低的点; 该点值=min(right-left)-mid w = 宽度
-
单调栈解法代码
点击查看代码
class Solution: def trap(self, height: List[int]) -> int: left = [0] * len(height) right = [0] * len(height) left[0] = height[0] for i in range(1,len(height)): left[i] = max(left[i-1],height[i]) right[-1] = height[-1] for i in range(len(height)-2,-1,-1): right[i] = max(right[i+1],height[i]) res = 0 for i in range(len(height)): res += min(left[i],right[i])-height[i] return res
-
双指针解法代码:
点击查看代码
class Solution: def trap(self, height: List[int]) -> int: st = [0] res = 0 for i in range(1,len(height)): while len(st)>0 and height[i]>height[st[-1]]: right = height[i] mid = height[st[-1]] st.pop() if len(st)>0: left = height[st[-1]] h = min(right,left)-mid w = i-st[-1]-1 res+=h*w st.append(i) return res
84.柱状图中最大的矩形
题解
-
目标:找比两侧都低的元素 最大的矩阵=该元素高度*宽度
-
双指针:
- 分别找每个点两侧最近的最高点
-
单调栈:
- 找到比两侧高的点:高度= 该点高度*宽度
- 最高点为mid
-
双指针法代码
点击查看代码
class Solution: def largestRectangleArea(self, heights: List[int]) -> int: size = len(heights) right = [0]*size left = [0]*size left[0] = -1 for i in range(1,size): tmp = i-1 while tmp>=0 and heights[tmp]>=heights[i]: tmp = left[tmp] left[i] = tmp right[size-1] = size for i in range(size-2,-1,-1): tmp = i+1 while tmp<size and heights[tmp]>=heights[i]: tmp = right[tmp] right[i] = tmp res = 0 for i in range(size): area = (right[i]-left[i]-1)*heights[i] res = max(res,area) return res
-
单调栈法代码
点击查看代码
class Solution: def largestRectangleArea(self, heights: List[int]) -> int: st = [0] heights.insert(0,0) # 防止栈底元素无法弹出 heights.append(0) # 防止最终结果无法计算 res = 0 size = len(heights) for i in range(1,size): while len(st)>0 and heights[i]<heights[st[-1]]: ##遇到凸型数据 right = i ##右边界 mid = st[-1] ##栈顶元素为最高值 st.pop() if len(st)>0: left = st[-1] ##左边界 w = right-left-1 area = heights[mid]*w res = max(area,res) st.append(i) return res
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构