【LeetCode】84. 柱状图中最大的矩形 结题报告 (C++)

本文介绍了一种解决LeetCode上最大矩形面积问题的有效算法。通过两次遍历柱状图,寻找以每个柱子作为最低点时能形成的最大矩形,并提出了一种使用栈来优化时间复杂度的方法。

原题地址:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/description/

题目描述:

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例:

输入: [2,1,5,6,2,3]
输出: 10
 

解题方案:

次遍历每一个位置i,以当前位置i为最低点,向右找比他大的,向左找比他大的,这就形成了一个区间,这个区间长度为左边比他大的个数+右边比他大的个数+他本身,这个区间的最短板就是当前位置i的高度,这样可以算出来以当前位置i为最低点的区间的面积,然后遍历所有位置,找到面积的最大值,时间复杂度为平方级别的,O(n^2)。最终的时间开销是比较大的,因此这种方法不是最好的解决方案。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int sz = heights.size();
        int ma = 0;
        for(int i = 0; i <s z; i++){
            int len = 1;
            int hei = heights[i];
            int sta = i-1, en = i+1;
            while(sta >= 0 && heights[sta] >= hei){
                len ++;
                sta --;
            }
            while(en < sz && heights[en] >= hei){
                len ++;
                en ++;
            }
            ma = max(ma, len * hei);
        }
        return ma;
    }
};

题目提示使用栈的方式解题,参考地址:https://blog.youkuaiyun.com/lv1224/article/details/79974175

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        stack<int> index;
        int area = 0;
        for(int i = 0; i < heights.size(); i++){
            if(index.empty() || heights[index.top()] < heights[i])  index.push(i);
            else{
                while(!index.empty() && heights[index.top()] >= heights[i]){
                    int tmp = index.top();
                    index.pop();
                    int length = 0;
                    if(index.empty()) length = i;
                    else length = i - index.top() - 1;
                    area = max(area, length * heights[tmp]);
                }
                index.push(i);
            }
        }
        while(!index.empty()){
            int tmp = index.top();
            index.pop();
            int length = 0;
            if(index.empty()) length = n;
            else length = n - index.top() - 1;
            area = max(area, length * heights[tmp]);
        }
        return area;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值