LeetCode84 85 柱状图中最大矩形

参考https://leetcode.wang/leetCode-84-Largest-Rectangle-in-Histogram.html

LeetCode 84

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
LeetCode84 85 柱状图中最大矩形_第1张图片

思路:遍历每一个柱子,找出以当前柱高作为高的最大矩形,其宽对应当前柱子左边第一个比它低的柱子右边第一个比它低的柱子
LeetCode84 85 柱状图中最大矩形_第2张图片
解法一:

int largestRectangleArea(vector<int>& heights) {
        int n=heights.size();
        if(n==0) return 0;
        //存储每个柱子左边第一个比它低的柱子的索引
        vector<int> leftLessMin(n,0);
        leftLessMin[0]=-1;
        for(int i=1;i<n;i++){
            int l=i-1;
            while(l>=0&&heights[l]>=heights[i]){
                l=leftLessMin[l];
            }
            leftLessMin[i]=l;
        }
        //存储每个柱子右边第一个比它低的柱子的索引
        vector<int> rightLessMin(n,0);
        rightLessMin[n-1]=n;
        for(int i=n-2;i>=0;i--){
            int r=i+1;
            while(r<n&&heights[r]>=heights[i]){
                r=rightLessMin[r];
            }
            rightLessMin[i]=r;
        }
        int maxArea=0;
        //求以每个柱子为高时的最大面积
        for(int i=0;i<n;i++){
            int area=(rightLessMin[i]-leftLessMin[i]-1)*heights[i];
            maxArea=max(area,maxArea);
        }
        return maxArea;
    }

解法二:利用栈巧妙解题

  1. 如果当前栈空,或者当前柱子大于栈顶柱子的高度,就将当前柱子的下标入栈
  2. 当前柱子的高度小于栈顶柱子的高度。那么就把栈顶柱子出栈,当做解法1中的当前要求面积的柱子。而右边第一个小于当前柱子的下标就是当前在遍历的柱子,左边第一个小于当前柱子的下标就是当前新的栈顶
int largestRectangleArea(vector<int>& heights) {
        int n=heights.size();
        if(n==0) return 0;
        stack<int> myStack;
        int maxArea=0;
        int area=0,l=0;
        for(int i=0;i<n;i++){
            if(myStack.empty()||heights[i]>=heights[myStack.top()]){
                myStack.push(i);
            }else{
                while(!myStack.empty()&&heights[i]<=heights[myStack.top()]){
                    int k=myStack.top();
                    myStack.pop();
                    if(!myStack.empty())  l=myStack.top();
                    else l=-1;
                    //这里i是rightLessMin,l是leftLessMin
                    area=(i-l-1)*heights[k];
                    maxArea=max(maxArea,area);
                }
                myStack.push(i);
            }
        }//遍历完成后,如果栈没有空,就依次出栈
        while(!myStack.empty()){
            int k=myStack.top();
            myStack.pop();
            if(!myStack.empty())  l=myStack.top();
            else l=-1;
            area=(n-l-1)*heights[k];
            maxArea=max(maxArea,area);
        }
        return maxArea;
    }

LeetCode 85

给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
LeetCode84 85 柱状图中最大矩形_第3张图片

解法一:

//解法一,横着的柱状图
    int maximalRectangle(vector<vector<char>>& matrix) {
        int m=matrix.size();
        if(m==0) return 0;
        int n=matrix[0].size();
        int maxArea=0;
        //width[i][j]保存第i行以当前数字结尾的连续 1 的个数
        vector<vector<int>> width(m,vector(n,0));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]=='1'){
                    if(j==0) width[i][j]=1;
                    else width[i][j]=width[i][j-1]+1;
                }  
                else width[i][j]=0;
                int minWidth=width[i][j];
                //matrix[0][0]~matrix[i][j]的最大矩形
                for(int k=i;k>=0;k--){
                    minWidth=min(minWidth,width[k][j]);
                    maxArea=max(maxArea,minWidth*(i-k+1));
                }
            }
        }
        return maxArea;
    }

解法二

//解法二,竖着的柱状图,height[i][j]就是柱子高度,然后就是Leetcode84的问题
    int maximalRectangle2(vector<vector<char>>& matrix){
        int m=matrix.size();
        if(m==0) return 0;
        int n=matrix[0].size();
        int maxArea=0;
        //height[i][j]保存第j列以当前数字(matrix[i][j])结尾的连续 1 的个数
        //这里height可以用一维
        vector<vector<int>> height(m,vector(n,0));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]=='1'){
                    if(i==0) height[i][j]=1;
                    else height[i][j]=height[i-1][j]+1;
                }  
                else height[i][j]=0;
            }
            //调用Leetcode84解法的largestRectangleArea函数
            maxArea=max(maxArea,largestRectangleArea(height[i]));
        }
        return maxArea;
    }

你可能感兴趣的:(算法,leetcode,数据结构,动态规划)