leetcode84——柱状图的最大矩形

单调栈的方法,每次弹出大于等于当前需要入栈的元素,且最后的栈是顺序递增的,需要将所有元素依次弹出,这个时候每个弹出的元素所对应的最大面积为index=stk.top(),stk.pop(),result_max=max(result_max,(len-stk.top()-1)*heights[index])

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int len=heights.size();
        stack<int>stk;
        stk.push(-1);
        int max_result=0;
        for(int i=0;i<len;i++)
        {
            if(stk.top()==-1||heights[stk.top()]<heights[i])
            {
                stk.push(i);
            }   
            else
            {
                
                while(stk.top()!=-1&&heights[stk.top()]>=heights[i])
                {
                    int index=stk.top();
                    cout<<index<<" "<<endl;
                    stk.pop();
                    max_result=max(max_result,(i-stk.top()-1)*heights[index]);
                }
                stk.push(i);
             }
        }
        cout<<stk.size()<<endl;
        int index_temp=stk.top();
        while(stk.top()!=-1)
        {
            int index=stk.top();
            stk.pop();
            //cout<<index<<" "<<index_temp<<" "<<stk.top()<<endl;
            max_result=max(max_result,(len-stk.top()-1)*heights[index]);
            //index_temp=index;
        }
        return max_result;
    }
};

 

方法二:记录左右边界的方法

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int len=heights.size();
        int max_result=0;
        vector<int>left;
        vector<int>right(len,0);
        stack<int>stk1;
        stack<int>stk2;
        stk1.push(-1);
        stk2.push(len);
        for(int i=0;i<len;i++)
        {
            while(stk1.top()!=-1&&heights[stk1.top()]>=heights[i])
            {
                stk1.pop();
            }
                left.push_back(stk1.top());
                stk1.push(i);
        }
         for(int i=len-1;i>=0;i--)
        {
            while(stk2.top()!=len&&heights[stk2.top()]>=heights[i])
            {
                stk2.pop();
            }
                cout<<stk2.top()<<endl;
                right[i]=stk2.top();
                stk2.push(i);
        }
        for(int i=0;i<len;i++)
        {
            //cout<<left[i]<<" "<<right[i]<<endl;
            max_result=max(max_result,(right[i]-left[i]-1)*heights[i]);
        }
        return max_result;
    }
};

方法二的优化:一遍遍历

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int len=heights.size();
        int max_result=0;
        vector<int>left;
        vector<int>right(len,len);
        stack<int>stk1;
        stack<int>stk2;
        stk1.push(-1);
        stk2.push(len);
        for(int i=0;i<len;i++)
        {
            while(stk1.top()!=-1&&heights[stk1.top()]>=heights[i])
            {
                right[stk1.top()]=i;
                stk1.pop();
            }
            left.push_back(stk1.top());
            stk1.push(i);
        }
         for(int i=len-1;i>=0;i--)
        {
            while(stk2.top()!=len&&heights[stk2.top()]>=heights[i])
            {
                stk2.pop();
            }
                cout<<stk2.top()<<endl;
                right[i]=stk2.top();
                stk2.push(i);
        }
        for(int i=0;i<len;i++)
        {
            //cout<<left[i]<<" "<<right[i]<<endl;
            max_result=max(max_result,(right[i]-left[i]-1)*heights[i]);
        }
        return max_result;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值