【LeetCode】84. 柱状图中最大的矩形

84. 柱状图中最大的矩形

知识点:单调栈

题目描述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例
输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10(以5为高的) 输入: heights = [2,4] 输出: 4

解法一:暴力法

以每个元素为中心向左右扩散,这个元素就是这个高度。

暴力法 class Resolution: def get_biggest(self, heights): max_area = 0 for i, height in enumerate(heights): p, q = i+1, i-1 while p < len(heights) and heights[p] >= height: p += 1 while q >= 0 and heights[q] >= height: q -= 1 area = height * (p-q-1) max_area = max(max_area, area) return max_area r = Resolution()

解法二:单调栈

上面的解法需要去寻找每个元素它左右两边第一个比它小的元素下标,这时候就可以确定宽度进而确定面积了。第一个比它大或者小的,这不就是可以用单调栈吗?
可以维持一个单调递增栈,if遇到更大的元素,那以它为高的矩形还不能确定,当遇到小的时候,对于栈顶元素而言,栈的下一个元素比其小,要入栈的比其小,所以矩形就确定了。
想一下栈里应该存什么,求面积无非就是宽乘以高,if存高度,那宽度就没有办法确定,但是if是存下标,那宽度和高度都可以确定。
对于单调栈的问题,重点是要弄清楚当元素出栈的时候,意味着什么。比如寻找一个数组里第一个比它大的元素,那就可以维持一个单调递减栈。当遇到大的元素时,出栈。这时候出栈就意味着找到了第一个比自己大的元素;对于这个题,出栈就意味着确定了以它为高的矩阵。

  • 未优化
class Resolution: def get_biggest(self, heights): max_area = 0 stack = [] for i, height in enumerate(heights): while stack and height < heights[stack[-1]]: cur_height = heights[stack.pop()] while stack and cur_height == heights[stack[-1]]: #可能存在相同的值; stack.pop() if stack: #栈为空和非空不一样 width = i - stack[-1] - 1 else: width = i area = cur_height * width max_area = max(max_area, area) stack.append(i) while stack: # 仍然在栈里的元素; cur_height = heights[stack.pop()] while stack and cur_height == heights[stack[-1]]: stack.pop() if stack: width = len(heights) - stack[-1] - 1 else: width = len(heights) max_area = max(max_area, cur_height * width) return max_area
  • 优化
    在首尾各加一个高度为0,这时候就不用单独判断了,因为任何值都会比0大,所以都会入栈,又因为任何值都比0大,所以都会出栈;
class Solution: def largestRectangleArea(self, heights: List[int]) -> int: size = len(heights) res = 0 heights = [0] + heights + [0] # 先放入哨兵结点,在循环中就不用做非空判断 stack = [0] size += 2 for i in range(1, size): while heights[i] < heights[stack[-1]]: cur_height = heights[stack.pop()] cur_width = i - stack[-1] - 1 res = max(res, cur_height * cur_width) stack.append(i) return res

相关链接

题解


__EOF__

本文作者Curryxin
本文链接https://www.cnblogs.com/Curryxin/p/16100474.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Curryxin  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
Live2D
欢迎阅读『【LeetCode】84. 柱状图中最大的矩形』
点击右上角即可分享
微信分享提示