NO.84 柱状图中的最大矩形

本文介绍了一种计算给定柱状图中最大矩形面积的算法,包括暴力法和更高效的单调递增栈法。通过实例展示,解释了如何通过优化算法提高执行效率。

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

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

 

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

 

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

//暴力法
void dfs(int *heights,int heightsSize,int *ret)
{
    if(heightsSize<=0)return;
    int min=heights[0],min_pos=0;
    for(int i=1;i<heightsSize;i++)
    {
        if(heights[i]<min)
        {
            min_pos=i;
            min=heights[i];
        }
    }
    int area=min*heightsSize;
    *ret=*ret<area?area:*ret;
    
    dfs(heights,min_pos,ret);
    dfs(heights+min_pos+1,heightsSize-1-min_pos,ret);
}

int largestRectangleArea(int* heights, int heightsSize){
    int ret=0;
    dfs(heights,heightsSize,&ret);
    return ret;
}
//单调递增栈法
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        //利用一个递增栈存储数组中的元素位置,当前位置高度小于栈顶元素对应高度时,栈顶元素出栈,直至当前位置元素可进栈
        //当前需进栈元素的位置为面积计算终点
        //栈顶元素出栈后,若栈为空,则当前位置前方所有位置大于栈顶元素
        //-1为面积计算起点,
        //若不为空,新的栈顶元素对应的位置为面积计算起点
        //高等于出栈元素对应的高度
        stack <int> increased_stack;
        //末尾压入0是为了让前方所有元素出栈
        heights.push_back(0);
        int area=0;
        for(int i=0;i<heights.size();i++)
        {
            while(!increased_stack.empty()&&heights[i]<heights[increased_stack.top()])
            {
                int top_tmp=increased_stack.top();
                increased_stack.pop();
                int start;
                if(increased_stack.empty())start=-1;
                else start=increased_stack.top();
                area=area<(heights[top_tmp]*(i-start-1))?(heights[top_tmp]*(i-start-1)):area;
            }
            increased_stack.push(i);
        }
        return area;
    }
};

示例:

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

//暴力法

执行用时 : 1884 ms, 在Largest Rectangle in Histogram的C提交中击败了34.38% 的用户

内存消耗 : 9 MB, 在Largest Rectangle in Histogram的C提交中击败了18.52% 的用户

//单调栈法

执行用时 : 20 ms, 在Largest Rectangle in Histogram的C++提交中击败了87.30% 的用户

内存消耗 : 10.9 MB, 在Largest Rectangle in Histogram的C++提交中击败了6.30% 的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值