leetcode解题笔记:84. Largest Rectangle in Histogram

题目地址:84. Largest Rectangle in Histogram

此题是求直方图中最大的矩形面积,思路就是:对于每一个高度为h直方图。找它左边第一个比它矮的位置i,右边第一个比他矮的位置j,那么以h为高度的最大矩形面积即为h*(j-i-1).

如题中高度为5的矩形,左边第一个比它矮的是高度为1的直方,位置是1,右边第一个比它矮的是高度为2的直方,位置为4,则高度为5的矩形最大面积为5*(4-1-1) = 10.

考虑利用栈来存储每一个直方与其左右第一个比它矮的直方的关系:
(1)第一个数为2,此时栈为空,则表示左侧没有比它小的,其矩形起始的i为0,将2入栈。
栈:2
(2)第二个数为1,发现1比栈顶元素2小,即此时找到了2的i和j,分别为0和元素1的位置1,那么此时以这个2为高的矩形面积即为2*1=2;既然已经计算完2这个直方所构成的矩形面积,则2出栈,1入栈。
栈:1
(3)第三个数5,比栈顶元素1大,因此5左边第一个比它小的元素就是1,5入栈。
栈:1,5
(4)第四个数6,比栈顶元素5大,因此6左边第一个比它小的元素就是5,6入栈。
栈:1,5,6
(5)第五个数2,同(2)中一样,发现比栈顶元素6小,那么就找到了6左边第一个比他小的元素就是6左侧的5,也找到了6右侧第一个比他小的元素就是现在的2,因此以6为高的矩形最大面积是6*(4-2-1) = 6(4是直方2的位置,2是直方5的位置)。6出栈。此时栈顶元素是5,发现元素2还是比当前的栈顶元素小,因此重复上述过程,5左侧第一个比它小的是1,右侧则是2,则最大面积为5*(4-1-1)=10。5出栈。此时栈顶元素是1,当前元素2比1大,2入栈。
栈:1,2
(6)第六个数3,比当前栈顶元素大,入栈。
栈:1,2,3
(7)此时已遍历完所有的直方,需继续处理剩下的这几个。假想最后一个直方右侧还有一个高度为-1的直方,则此虚拟直方是当前剩下这几个直方右侧第一个比他们小的。所以对3来说,左侧第一个比它小的是2,右侧是0,则它的矩形面积是3*(6-4-1) = 3。3出栈。对2同理:2*(6-1-1) = 8;2出栈;对1同理:1*(6-0)=6;1出栈。栈为空,程序结束。


上面详细的分析了一下过程,有以下几个要点:

  • 计算每一个矩形面积,宽度是右侧第一个比元素小的元素下标-左侧第一个比元素小的下标-1;因此为了方便,在stack中存的是每一个直方的下标
  • 当栈中只有一个元素时的矩形计算情况与上一点的普视情况不同,此时的宽度直接是右侧第一个比元素小的元素的下标。
  • 在遍历结束后假想有一个高度为-1的直方很重要,这帮助我们处理完所有的直方。

public class Solution {
    public int largestRectangleArea(int[] heights) {
       Stack<Integer> stack = new Stack<Integer>();
       int max = 0;
       for (int i = 0; i <= heights.length; i++) {
       //curt用来表示遍历到的当前元素的高或假想直方高-1
            int curt = (i == heights.length) ? -1 : heights[i];
            //当前元素比栈顶元素小时,栈顶元素出栈,计算面积
            while (!stack.isEmpty() && curt <= heights[stack.peek()]) {
                int h = heights[stack.pop()];
                int w = stack.isEmpty() ? i : i - stack.peek() - 1;
                max = Math.max(max, h * w);
            }
            stack.push(i);
        }
       return max;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值