代码随想录算法训练营第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
    
posted @   哆啦**  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示