[LeetCode]84. Largest Rectangle in Histogram

本文解析了LeetCode第84题“直方图中的最大矩形”这一算法问题,介绍了通过栈来实现高效求解的方法。文章详细解释了如何利用栈维护递增序列并计算最大矩形面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[LeetCode]84. Largest Rectangle in Histogram

题目描述

这里写图片描述

思路

开始的想法,对每个点,左右搜索比他小的元素并计数,返回结果乘
但是这种做法会超时

看了答案的栈的做法

如果对于有序数组
1,2,3
那么返回的结果是max(1 * 3, 2 * 2, 3 * 1)

对于无序数组的处理方式,借助栈
以题目中的样例为例
数组–[2, 1, 5, 6, 2, 3]
开始,栈为空
2入栈
此时栈中元素 {2}
对下一个元素1,小于栈顶元素2,入栈的话不满足有序的条件,因此2出栈,同时更新最大结果 res = 2 * 1 = 2
之后对于1,可以延伸到2,为保持有序,将之前出栈的元素2按照当前元素1的大小入栈,并将1入栈
此时栈中元素{1, 1}
对下一个元素5,大于栈顶元素1,入栈
此时栈中元素{1, 1, 5}
对下一个元素6,大于栈顶元素5,入栈
此时栈中元素{1, 1, 5, 6}
对下一个元素2,小于栈顶元素6,入栈后不满足有序条件,因此将栈顶元素6出栈,更新最大结果res = (max, 6 *1) = 6
此时栈中元素{1, 1, 5}
继续使用2和栈顶元素5比较,不可以入栈,因此栈顶元素5出栈,更新最大结果res = max(res, 5 * 2) = 10
此时栈中元素{1,1}
此时2大于栈顶元素1,符合入栈条件,入栈前,将之前出栈的5,6按照当前元素2的大小入栈,之后再将2入栈
此时栈中元素为{1, 1, 2, 2, 2}
对于下一个元素3, 大于栈顶元素2,入栈
对原数组遍历完成

之后处理栈
当栈不为空时
计算栈顶元素 * (count++),若符合更新结果条件,则更新结果。
直到栈为空

得到最终结果

代码

#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;

class Solution {
public:
    int largestReactangleArea(vector<int>& heights) {
        /*
        int len = heights.size(), res = 0;
        for (int i = 0; i < len; ++i) {
            int count = 0;
            if (i != 0 && heights[i] == heights[i - 1])
                continue;
            for (int k = i - 1; k >= 0; --k) {
                if (heights[k] >= heights[i])
                    ++count;
                else
                    break;
            }
            for (int k = i; k < len; ++k) {
                if (heights[k] >= heights[i])
                    ++count;
                else
                    break;
            }

            res = res > count * heights[i] ? res : count * heights[i];
        }
        return res;
        */

        int res = 0, count = 0;
        stack<int> s;
        for (int p : heights) {
            if (s.empty() || s.top() <= p) {
                s.push(p);
            }
            else {
                while (s.size() > 0 && s.top() > p) {
                    ++count;
                    res = max(res, count * s.top());
                    s.pop();
                }
                while (count) {
                    s.push(p);
                    --count;
                }
                s.push(p);
            }
        }
        while (!s.empty()) {
            ++count;
            res = max(res, count * s.top());
            s.pop();
        }

        return res;
    }
};

int main() {
    vector<int> nums = { 2,1,5,6,2,3 };
    Solution s;
    cout << s.largestReactangleArea(nums) << endl;
    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值