84. 柱状图中最大的矩形*【力扣】

题意理解

给定一个数组,计算数组框起来的最大面积。

问题分析

用单调栈,控制出入栈。

栈中存放当前元素的索引值(用于计算面积),若递增,当前元素索引入栈,若递减,出栈栈顶元素(是一个索引),计算前一个索引和当前索引的差值,再乘上栈顶索引对应的元素值得到最大面积。直到栈顶元素小于当前元素。 最后再将当前元素索引入栈。

其他

思想神奇。单调栈的记忆功能,选择性记忆

https://leetcode-cn.com/problems/largest-rectangle-in-histogram/

链接

    int largestRectangleArea(vector<int>& heights) {
        heights.push_back(0);    //补一个0,支持最后清栈
        int len = heights.size();
        
        stack<int> st;
        int area = 0;
        for (int i = 0; i != heights.size(); i ++) {    //遍历数组
            while (!st.empty() && heights[i] < heights[st.top()]) {    //找到非递增的第一个元素
                int h = heights[st.top()];    //取出栈顶对应的高度
                st.pop();    //弹栈
                int idx = 0;
                if (!st.empty()) {    //栈不空
                    idx = st.top();    //取元素
                }
                else {
                    idx = -1;    //栈空,设置为-1
                }
                area = max (area, h * (i - idx - 1));   //计算索引差值,得到最大面积             
            }
            st.push(i);    //入栈
        }
        return area;
    }
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int len = heights.size();
        if (len == 0) {
            return 0;
        }
        stack<int> my_stack;  //存放序号  单调栈 递增栈

        vector<int> lefts;  //存放序号
        for (int i = 0; i < heights.size(); i++) {
            //找到最左边的高度边界
            while(!my_stack.empty() && heights[i] <= heights[my_stack.top()]) {
                my_stack.pop();
            }

            lefts.push_back(my_stack.empty() ? -1 : my_stack.top());
            my_stack.push(i);
        }
        /*
        for(auto left:lefts) {
            cout << left << '\t';
        }
        cout << endl;
        */
        //stack<int> my_stack;  //存放序号
        while(!my_stack.empty()) {
            my_stack.pop();
        }
        vector<int> rights(len);  //存放序号
        for (int i = len-1; i >= 0 ; i--) {
            //找到最右边的高度
            while(!my_stack.empty() && heights[i] <= heights[my_stack.top()]) {
                my_stack.pop();
            }
            rights[i] = my_stack.empty() ? len : my_stack.top();
            my_stack.push(i);
        }
        /*
        for(auto right:rights) {
            cout << right << '\t';
        }
        cout << endl;
        */
        int max_area = INT_MIN;
        for (int i = 0; i < len; i++) {
            int curr_area = heights[i] * (rights[i] - lefts[i] - 1);
            if (max_area < curr_area) {
                max_area = curr_area;
            }
        }
        return max_area;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值