算法:柱状图中最大的矩形

本文详细解析了如何找到柱状图中最大的矩形面积问题,通过分析暴力解法并逐步优化,提出了利用栈来解决此问题的高效算法。在遍历过程中,遇到较小元素时进行出栈操作,最终确定矩形边界,时间复杂度为O(n),空间复杂度也为O(n)。
摘要由CSDN通过智能技术生成

题目:柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例:

输入: [2,1,5,6,2,3]
输出: 10

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram

分析

拿到这道题,先不要想其他的方法,看看暴力解法能不能算出来。我们会发现暴力算法有两个方案:一个是变化矩形的范围,然后求出范围中的最低柱子,就可以得到面积了。第二个是每个柱子分别向前后扩散,遇到比自己低的就停下来,那么这个范围的宽度乘上自身的高度,就是该位置的柱子可以达到的最大面积。(第二种我当时没想出来==)

然后我们从暴力算法中,看看有没有可以进行优化的地方。首先两种思路,第一种的话因为已经固定了两层嵌套循环,要去优化的话显然有点困难。第二种的思路只有一个外层循环,所以优化的空间可能会比较大,我们从第二种入手。

首先我们知道,第二种思路最费时间的点就是每次都要前后去寻找,那我们这里可以去想一下怎么把前面遍历的情况记录下来,节省时间。所以难点就是在确定边界。

重要特点:这里我们分析边界的特点。如果i < j ,且heights[i] > heights[j] ,这样的话,对于任何 j < k,第K个元素的左边界不可能是i。因为被 j 挡住了。这个应该很好理解吧。可以的话我们继续。

首先我们进行遍历数组,看什么时候可以确定边界。假设现在有[2,4,1,5,7,3]。(大家可以自行画图体验,我这里就不画图了,懒癌犯了)

  1. 遍历到2的时候,已经确定好左边界,但是还没有确定右边界;
  2. 遍历4,同二。
  3. 遍历1,这个时候我们会发现,第二个元素4,已经确定好边界了,可以得出面积4.
  4. 然后可以发现第一个元素2,也得到他的边界了。
  5. 然后我们会发现,位置1 比前面的任何元素都要小,那么后面的元素,不可能以2,4为左边界。原因看上面。
  6. 然后同理继续遍历5,和7.然后遍历到3的时候,元素 7 也确定边界了。元素5也确定边界了。
  7. 后面已经没有元素了,所以3也可以确定边界。最后再确定1的边界。

观察上面的流程,有没有一丝丝什么的味道?栈的味道。遍历可以看做是入栈,确定边界的时候,可以看成出栈。先进后出。那么可不可以用一个辅助栈来完成这个流程呢?答案是肯定的。

思路和上面一模一样,重点是入栈和出栈。从上面的重要特点可以知道,当遇到比较小的元素的时候,那么前面的元素就可以确定边界了,进行出栈操作。所以栈底,永远是前面的最小元素。

  1. 当遍历到的元素比栈顶要小的时候,那么就可以对栈顶元素进行出栈
  2. 这个矩形的高度是栈顶元素的高度,宽度是当前遍历到的元素的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值