LeetCode-栈-单调栈

1 直方图最大矩形面积

剑指 Offer II 039. 直方图最大矩形面积

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        //单调递增栈
        stack<int> s;//s中保存的是直方图的索引
        s.push(-1);//-1相当于一个sentinel
        int maxArea = 0;
        for (int i = 0; i < heights.size(); ++i) 
        {
            //若当前柱高<=栈顶柱高,将栈顶柱子出栈,并计算栈顶柱子为顶的最高矩阵面积,直至可入栈
            //出栈的目的是在“栈顶->栈底”的方向上找到第一个“高度小于当前柱子的高度”元素,这样,被找到的这个元素和当前元素之间(不含这两个边界元素)夹着的矩形可勾勒出最大面积的矩形
            while (s.top() != -1 && heights[s.top()] >= heights[i]) 
            {
                int height = heights[s.top()];
                s.pop();
                int width = i - s.top() - 1;
                maxArea = max(maxArea, height * width);
            }
            //若当前柱高>栈顶柱高,那么该柱子下标入栈
            s.push(i);
        }
        //[1,2,3,4,5]如果按照这个顺序入栈,在上面的过程中是没有机会进行入栈的操作,所以这里还要进行计算一次
        while (s.top() != -1) 
        {
            int height = heights[s.top()];
            s.pop();
            int width = heights.size() - s.top() - 1;
            maxArea = max(maxArea, height * width);
        }
        return maxArea;        
    }
};

2 最大矩形

85. 最大矩形

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int area=0;
        if(matrix.size() ==0 || matrix[0].size() ==0)
            return 0;
        int rows = matrix.size();
        int cols = matrix[0].size();
        vector<int> rectangular(cols);
        
        for(auto& nums:matrix)
        {
            for(int j=0; j<cols; ++j)
            {//把矩阵的矩阵形式,构造成同上一题的“直方图最大矩形”
            //也就是每次看一行数据,这一行看做直方图。下一行“1”能和上一行接上就累加,数值就代表矩形高度
            //不然下一行的高度就归零。
                if(nums[j] == '1')
                {
                    rectangular[j]++;
                }
                else
                {
                    rectangular[j]=0;
                }
            }

            area = max(area, largestRectangleArea(rectangular));
        }

        return area;
    }

    //https://leetcode-cn.com/problems/0ynMMM/ 同样的题目
    int largestRectangleArea(vector<int>& heights) {
        int len = heights.size();
        int area=0;
        //栈的目的:不用重复遍历所有匹配,查找可得左右边界情况
        stack<int> stk;//存储的是数组的索引值。单调栈,从底到顶,数字为从小到大
        stk.push(-1);
        int wide, height;
        int i=0;
        for(; i<len; ++i){//数组遍历(可能会计算之间部分面积)
        // 新添加元素小于栈顶元素:栈顶元素为height的,矩形右边界能确定
            while(stk.top() !=-1 && heights[stk.top()]>=heights[i]){
                height = heights[stk.top()];stk.pop();
                wide = i - stk.top()-1;
                area = max(area, height*wide);
            }
        // 新元素大于栈顶元素:栈顶元素为height的矩形右边界没法确定。(直接入栈)
            stk.push(i);
        }

        while(stk.top() != -1){//再遍历栈中剩下的元素,栈中都是从小到大排列,计算面积就很有规律了
            height = heights[stk.top()];
            stk.pop();
            wide = len - stk.top()-1;
            area = max(area, height*wide);
        }
        return area;
    }    
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值