LintCode-直方图最大矩形覆盖

直方图最大矩形覆盖

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.

histogram

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

histogram

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

分析一下可以发现,在直方图的某一位置i,对于其左边任何不低于height[i]的bar的高度height[j],并不会对该位置所构成的最大矩形产生影响。如题目样例[2,1,5,6,2,3]中,对于位置i=1,无论样例是[2,1,5,6,2,3]、[1,1,5,6,2,3]还是[5,1,5,6,2,3]都不会影响i=1是的最大矩形面积max=2。
因此只要保存从开始到i-1位置的高度递增序列,在位置i更新最大矩形max。比较i位置的bar与序列最后元素的高度:
当bar.y>h.back().y时,将bar直接加入序列h;
而bar.y<=h.back().y时,丢弃先前序列中高度小于bar的元素。

注意删除时忘了j–会跳过一个元素

class Solution {
public:
    /**
     * @param height: A list of integer
     * @return: The area of largest rectangle in the histogram
     */
    struct increase{
        int x,y;
    };
    int largestRectangleArea(vector<int> &height) {
        // write your code here
        vector<increase> h(1);
        h[0].x=-1;
        h[0].y=0;
        int max=0;
        for(int i=0;i<height.size();i++)
        {
            increase t;
            t.x=i;
            t.y=height[i];
            for(int j=0;j<h.size();j++)
            {
                auto s=(i-h[j-1].x)*min(h[j].y,t.y);
                if(s>max)
                {
                    max=s;
                }
                if(h[j].y>=t.y)
                {
                    //delete
                    h.erase(h.begin()+j);
                    j--;
                }
            }
            h.push_back(t);
            auto s=(i-h[h.size()-2].x)*t.y;
            max=s>max?s:max;
        }
        return max;
    }
};

结果超时了,可以看出并不是所有位置都需要计算max。新增的bar是不需要计算max的,因为后面的bar高度可能高于该bar,因此,在删除元素时进行最大矩形的计算可以节省时间。
另一方面,只有增加了只有处于高度递增序列最大值的元素才需要计算并更新最大矩形max,而其之前的最大矩形必定小于该位置的最大矩形。因此加入max_x记录当前计算过的最大矩阵的下标位置,当删除元素时,只有当前下标大于max_x的位置才进行计算。

在序列前后分别加入高度为-1,0的元素以省去判断过程。两个高度不能一样,否则就会变成成未递增的序列而被删除。

class Solution {
public:
    /**
     * @param height: A list of integer
     * @return: The area of largest rectangle in the histogram
     */
    struct increase{
        int x,y;
    };
    int largestRectangleArea(vector<int> &height) {
        // write your code here
        vector<increase> h(1);
        h[0].x=-1;
        h[0].y=-1;
        //在序列前加入-1
        height.push_back(0);
        //在序列后加入0
        int max=0;
        //当前最大矩形面积
        int max_x=-1;
        //当前比较过最大矩形的最后下标,注意不能设成0,否则从第二个元素开始算
        for(int i=0;i<height.size();i++)
        {
            increase t;
            t.x=i;
            t.y=height[i];
            while(t.y<=h.back().y)//未递增
            {
                if(h.back().x>max_x)
                {
                    for(int j=1;j<h.size();j++)
                    {
                        auto s=(h.back().x-h[j-1].x)*h[j].y;
                        if(s>max)
                        {
                            max=s;
                        }
                    }
                    max_x=h.back().x;
                }
                h.pop_back();
            }
            h.push_back(t);
        }
        return max;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值