LeetCode No.84 Largest Rectangle in Histogram 题解

LeetCode No.84 Largest Rectangle in Histogram 题解

题目描述


Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
For example,
Given heights = [2,1,5,6,2,3],
return 10.


题目分析

这道题大意是将一个数组看作是直方图。求这个直方图内的最大矩形面积。

题干实在是简单。但是也实在开始没想到什么好方法。 索性先暴力做试试。

方法一 暴力穷举求解

这个方法很朴素。 就是穷举起点终点。然后算面积。 最后取最大值。就完了。
很明显的,一个 O(n2) 的方法。但是! 注意不要写成了 O(n3)
原因在于, 枚举起点终点的同时,需要记录下这个区间内的最小值。 不然计算高度的时候还得循环一遍。

代码如下:


好的,交上去果然超时了。我就知道一道Hard的题不可能这么简单。

但是这超时数据就很有意思了,
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1...]
emmm…..这种数据很容易就让人想到一种改进方法。

方法二 暴力求解改进版

唔。。。之所以这样叫, 是因为复杂度上并没有得到改进。还是 O(n2) .
回到这个问题, 其实有一个明显的事实。我们刚才暴力求解其实做了许多无用运算。这是因为, 对于一个区间[i,j]
,若其矩形面积最大, 必然有nums[i - 1] < nums[i] && nums[j + 1] < nums[j].利用反证可以轻松证得这个结论。
利用这个性质,可以轻松写出2个条件来约束查找的范围。
还有一个,就是当相邻多个相等时, 我们是可以把这些点合并起来的。因为他们一定同时被选或者同时不被选。
嗯, 这样写完提交。 发现可以过了。 不过复杂度还是 O(n2) . 代码如下:


方法三 利用stack解

上面那种显然还是比较暴力。 这种方法就是 O(n) 复杂度了。
怎么来描述这种方法呢?大致过程如下:
1. 首先将数组元素依次入栈。
2. 每次元素入栈时, 将入栈元素与栈顶元素相比。如果栈顶元素值更小,那么元素直接入栈。更大的话,弹出栈顶元素,并更新最大值。

这个方法其实感觉挺容易的。。。一开始自己却没有想到。囧了。。
代码:

  class Solution {
    public:
    int largestRectangleArea(vector<int> &height) {

        int ret = 0;
        height.push_back(0);
        vector<int> index;

        for(int i = 0; i < height.size(); i++)
        {
            while(index.size() > 0 && height[index.back()] >= height[i])
            {
                int h = height[index.back()];
                index.pop_back();

                int sidx = index.size() > 0 ? index.back() : -1;
                if(h * (i-sidx-1) > ret)
                    ret = h * (i-sidx-1);
            }
            index.push_back(i);
        }

        return ret;
    }
    };

其他细节

注意上面用栈的那个方法。 头尾要加上0, 不然会有问题。加上0才能保证搜索对解集是闭合的。

PS: 国庆有点小偷懒。。写的不多。 之后慢慢补回来吧:)

The End.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值