leetcode84.柱状图中最大的矩形

1.题目描述

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

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

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

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

 

示例:

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

2.解题思路

思路:
首先,要想找到第 i 位置最大面积是什么?

是以i 为中心,向左找第一个小于 heights[i] 的位置 left_i;向右找第一个小于于 heights[i] 的位置 right_i,即最大面积为 heights[i] * (right_i - left_i -1),如下图所示:

1559826097853.png


所以,我们的问题就变成如何找 right_i 和 left_i?

利用单调栈,我们需要一个递增栈,当遇到大的数字直接进栈,而当遇到小于栈顶元素的数字时,就要取出栈顶元素进行处理了(栈顶元素相当于heights[i]),于是乎遇到的较小的数字只是一个触发,表示现在需要开始计算矩形面积了,为了使得最后一块板子也被处理,这里用了个小 trick,在高度数组最后面加上一个0,这样原先的最后一个板子也可以被处理了。由于栈顶元素是矩形的高度,那么关键就是求出来宽度,单调栈中不能放高度,而是需要放坐标。由于我们先取出栈中最高的板子,那么就可以先算出长度为1的矩形面积了,然后再取下一个板子,此时根据矮板子的高度算长度为2的矩形面积,以此类推,直到数字大于栈顶元素为止,再次进栈,巧妙的一比!宽度 (i-stack[-1]-1) ,其中i相当于上图的 right_i(向右找第一个小于于 heights[i] 的位置 right_i),其中stack[-1]相当于上图的 left_i (向左找第一个小于 heights[i] 的位置 left_i)

在首尾加了两个0,这个设计真的很精妙啊,我开始用栈这个方法去解决问题的时候,就在考虑如果遍历之后,栈不为空,那么还需要一步:即弹出栈中所有元素,分别计算最大面积。然而当加了两个0以后,在结束后,栈一定为空! 

首部加0是因为在计算宽度(i-stack[-1]-1)时需要stack[-1]

参考:https://www.cnblogs.com/grandyang/p/4322653.html

参考:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/solution/zhao-liang-bian-di-yi-ge-xiao-yu-ta-de-zhi-by-powc/

 

3.代码实现

class Solution(object):
    def largestRectangleArea(self, heights):
        """
        :type heights: List[int]
        :rtype: int
        """
        heights = [0] + heights + [0]
        size = len(heights)
        stack = []
        res = 0
        i = 0
        while i < size:
            # 加入=是因为前后都插入了额外的0,我了让最后的0可以进来。
            if not stack or heights[i] >= heights[stack[-1]]:
                stack.append(i)
                i+=1
            else:
                t = stack.pop(-1)
                res = max(res,heights[t]*(i-stack[-1]-1))
        return res

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值