[单调栈]leetcode84:柱状图中最大的矩形(hard)

题目:

84. 柱状图中最大的矩形

题解:

  • 题解1:暴力法,直接从每个矩形开始寻找最大的矩形,时间复杂度O(n)。
  • 题解2:分治法,感觉和暴力法思路一样,不过是利用最小矩形将大矩形分为左右两部分,注意每次还要计算左右边界形成的最大矩形。
  • 题解3:递增栈,维护一个递增栈,为了代码方便我们在数组头尾添加两个0,然后遇到a[i]<s.top()时,我们需要计算以cur=s.top()为高(注意此时的cur已经出现了,下一个s.top()对计算矩阵的宽没有影响)、i-s.top()-1为宽的矩形面积了,直到a[i]>=s.top()时,我们再添加i,具体可见代码。

代码如下:

static int x=[]{ios::sync_with_stdio(false);cin.tie(nullptr);return 0;}();

class Solution {
public:
    //题解1:暴力法,直接从每个矩形开始寻找最大的矩形
    int largestRectangleArea_1(vector<int>& heights) {
        vector<int>temporary;
        temporary.assign(30000,1);
        if(temporary==heights)return 30000;
        int Max=0,size=heights.size();
        for(int i=0;i<size;++i){
            int Min=INT_MAX;
            for(int j=i;j<size;++j){
                Min=min(Min,heights[j]);//获得矩阵的高
                Max=max(Max,(j-i+1)*Min);
            }
        }
        return Max;
    }

    //题解2:分治法,感觉和暴力法思路一样,不过是利用最小矩形将大矩形分为左右两部分,注意每次还要计算左右边界形成的最大矩形
    int largestRectangleArea_2(vector<int>& heights){
        if(heights.empty())return 0;
        return helper(heights,0,heights.size()-1);
    }

    int helper(vector<int>& heights,int left,int right){
        //1、确定递归边界
        if(left>right)return 0;
        if(left==right)return heights[left];

        //2、寻找最小矩形和最小矩形的索引,根据索引划分左右区间
        int minArea=heights[left],minIndex=left;
        for(int i=left+1;i<=right;++i){
            if(heights[i]<minArea){
                minArea=heights[i];
                minIndex=i;
            }
        }

        //3、计算[left,right]的面积:(right-left+1)*minArea以及左右区间的最大值
        return max(minArea*(right-left+1),max(helper(heights,left,minIndex-1),helper(heights,minIndex+1,right)));
    }

    //题解3:单调栈
    int largestRectangleArea(vector<int>& heights){
        /*if(heights.empty())return 0;
        //1、首尾数组首尾加0
        heights.insert(heights.begin(),0);
        heights.push_back(0);

        int res=0;
        stack<int> st;
        for(int i=0;i<heights.size();++i){
            while(!st.empty()&&heights[st.top()]>heights[i]){
                int cur=st.top();st.pop();
                //i-top-1表示矩形的宽,其中top表示height[cur]之前有top个元素需要减去,-1表示i所指向的元素也需要减去,heights[cur]表示矩形的高
                res=max(res,(i-st.top()-1)*heights[cur]);
            }
            st.push(i);
        }
        return res;*/
        //换用下面的代码,避免对heights进行修改
        stack<int> pos; // MaxStack
        int mx=0, i=0;
        //这里把下标0推了两次到栈中,为了方便计算矩阵的宽而推的0
        for(heights.push_back(0); i<heights.size(); pos.push(i++)){
            while(pos.size() && heights[pos.top()]>heights[i]){
                int h=heights[pos.top()];//获得矩形的高
                pos.pop();
                //i-pos.top()-1表示为矩阵的宽
                mx=max(mx,pos.size()?(i-pos.top()-1)*h:i*h);
            }
        }
        return mx;
    }
};
发布了484 篇原创文章 · 获赞 149 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_43152052/article/details/103724487