[leetcode] 84. Largest Rectangle in Histogram

Givenn 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.


Above is a histogram where width of each bar is 1, given height =[2,1,5,6,2,3].


The largest rectangle is shown in the shaded area, which has area =10 unit.

For example,

Given height =[2,1,5,6,2,3],

return10.

这道题是求柱状图中最大矩形面积,题目难度为Hard。

我们可以依次求出到当前立柱为止的最大矩形面积,这样递推到最后一个立柱也就找到了最终的结果。最大矩形如果不包含当前立柱,则和上一立柱的最大矩形面积相同,如果包含当前立柱,则依次求出之前所有矩形的大小取其中最大的即是当前的最大矩形。这里用到了动态规划的策略,具体代码:

class Solution {
public:
    int largestRectangleArea(vector<int>& height) {
        if(height.empty()) return 0;
        
        vector<int> maxArea(height.size(), INT_MIN);
        
        maxArea[0] = height[0];
        for(int i=1; i<height.size(); i++) {
    		int minHgt = height[i];
    		maxArea[i] = maxArea[i-1];
    		for(int j=i; j>=0; j--) {
    			minHgt = min(minHgt, height[j]);
    			maxArea[i] = max(maxArea[i], minHgt*(i-j+1));
    		}
        }
        
        return maxArea.back();
    }
};

虽然解决了问题,但并没有通过测试,在大集合测试时超时了。上面DP策略实现的时间复杂度是O(n2),有没有其他的方法呢?

我们知道最大矩形的高度肯定是某一个立柱的高度,确定这点很重要。那么以某一立柱为高度的最大矩形怎么确定呢?假定有n个立柱,前n-1个立柱的高度依次递增,而第n个立柱的高度低于第n-1个立柱,也就是出现所谓的波峰了。这时前面比第n个立柱高的立柱所确定的最大矩形就可以计算了,因为要以这些立柱为高度,所以这些矩形不会包含第n个立柱以及比第n个立柱低的立柱。这样就可以把这些立柱排除在外继续查看后续的立柱,排除这些立柱之后其他的立柱又一次递增了,这样依次遍历所有立柱就得到了所有比最后立柱高的立柱所确定的矩形面积。最后剩下的就是一个递增的立柱序列,而其他排除在外的立柱所确定的最大矩形都已经进行了计算,这样以剩下的立柱为高度所确定的最大矩形就很好计算了。这里记录递增立柱需要用到栈,算法时间复杂度达到了O(n),具体代码:

class Solution {
public:
    int largestRectangleArea(vector<int>& height) {
        stack<int> idx;
        int maxArea = 0;
        
        for(int i=0; i<height.size(); i++) {
            if(idx.empty() || height[i]>=height[idx.top()]) {
                idx.push(i);
            }
            else {
                int preIdx = idx.top();
                idx.pop();
                maxArea = max(maxArea, height[preIdx]*(idx.empty() ? i : (i-idx.top()-1)));
                i--;
            }
        }
        
        int sz = height.size();
        while(!idx.empty()) {
            int preIdx = idx.top();
            idx.pop();
            maxArea = max(maxArea, height[preIdx]*(idx.empty() ? sz : (sz-idx.top()-1)));
        }
        
        return maxArea;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值