84. Largest Rectangle in Histogram

这里写图片描述
第一种方法:
开始想到的是暴力求解,用两个循环,每个循环求一次最大面积,这样时间复杂度为O(N^2),结果time error。

public:
    int largestRectangleArea(vector<int>& heights) 
    {
        int m=heights.size();
        int i,j,minheight,area;
        area=0;
        for(i=0;i<m;i++)
        {
            minheight=heights[i];
            for(j=i;j<m;j++)
            {
                if(heights[j]<minheight)
                    minheight=heights[j];
                area=minheight*(j-i+1)>area?minheight*(j-i+1):area;
            }
        }
        return area;
    }
};

第二种方法:使用栈
原理:
1、如果已知height数组是升序的,应该怎么做?

比如1,2,5,7,8

那么就是(1*5) vs. (2*4) vs. (5*3) vs. (7*2) vs. (8*1)

也就是max(height[i]*(size-i))

2、使用栈的目的就是构造这样的升序序列,按照以上方法求解。

但是height本身不一定是升序的,应该怎样构建栈?

比如2,1,5,6,2,3

(1)2进栈。s={2}, result = 0

(2)1比2小,不满足升序条件,因此将2弹出,并记录当前结果为2*1=2。

将2替换为1重新进栈。s={1,1}, result = 2

(3)5比1大,满足升序条件,进栈。s={1,1,5},result = 2

(4)6比5大,满足升序条件,进栈。s={1,1,5,6},result = 2

(5)2比6小,不满足升序条件,因此将6弹出,并记录当前结果为6*1=6。s={1,1,5},result = 6

2比5小,不满足升序条件,因此将5弹出,并记录当前结果为5*2=10(因为已经弹出的5,6是升序的)。s={1,1},result = 10

2比1大,将弹出的5,6替换为2重新进栈。s={1,1,2,2,2},result = 10

(6)3比2大,满足升序条件,进栈。s={1,1,2,2,2,3},result = 10

栈构建完成,满足升序条件,因此按照升序处理办法得到上述的max(height[i]*(size-i))=max{3*1, 2*2, 2*3, 2*4, 1*5, 1*6}=8<10

综上所述,result=10

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) 
    {
        int area=0,i;
        stack<int>temp;
        for(i=0;i<heights.size();i++)
        {
            if(temp.empty())
                temp.push(heights[i]);
            else
            {
                if(heights[i]>=temp.top())
                    temp.push(heights[i]);
                else
                {
                    int count=1;
                    while(!temp.empty()&&heights[i]<temp.top())
                    {
                        area=temp.top()*count>area?temp.top()*count:area;
                        temp.pop();
                        count++;
                    }
                    while(count)
                    {
                        temp.push(heights[i]);
                        count--;
                    }
                }
            }
        }
        int num=1;
        while(!temp.empty())
        {
            if(temp.top()*num>area)
            {
                area=temp.top()*num;
            }
            num++;
            temp.pop();
        }
        return area;
    }
};

简化版

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) 
    {
        int area=0,i;
        stack<int>temp;
        for(i=0;i<heights.size();i++)
        {
            while(!temp.empty()&&heights[i]<heights[temp.top()])
            {
                int h=heights[temp.top()];
                temp.pop();
                int s=h * (temp.empty() ? i : (i - temp.top() - 1));
                area=area>s?area:s;
            }
            temp.push(i);
        }
        while(!temp.empty())
        {
            int h=heights[temp.top()];
            temp.pop();
            int s=h * (temp.empty() ? heights.size() : (heights.size() - temp.top() - 1));
            area=area>s?area:s;
        }
        return area;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值