【单调栈】84. 柱状图中最大的矩形——数据结构经典问题求解思路

【单调栈】84. 柱状图中最大的矩形——数据结构经典问题求解思路

该问题属于虽然是困难模式,但是却是数据结构的一个经典问题,该问题的求解方法包括:暴力法、单调栈方法。建议读者先掌握暴力法的求解思路,之后出于优化该算法的目的,提出了单调栈算法。

84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。
在这里插入图片描述

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

1、暴力法

我们知道,求矩形的面积需要知道矩形的长和宽,而在该题目中宽度即不同柱形之间距离,长度为柱形的高度。因此,我们可以设计一个算法,使用双层for循环来定一移一,通过观察我们发现可以固定宽度、遍历高度,依次求得所有可能的面积情况。

具体地,我们可以固定某一个柱形,依次往后遍历,每遍历一次,宽度就加一,直到遇到比该柱形高度要低的情况,此时该柱形所能计算的最大面积即等于其高度*宽度。

详细的代码如下(c++):

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        int ans = 0;
        // 枚举左边界
        for (int left = 0; left < n; ++left) {
            int minHeight = INT_MAX;
            // 枚举右边界
            for (int right = left; right < n; ++right) {
                // 确定高度
                minHeight = min(minHeight, heights[right]);
                // 计算面积
                ans = max(ans, (right - left + 1) * minHeight);
            }
        }
        return ans;
    }
};

该算法的时间复杂度为 O ( n 2 ) O(n^2) O(n2),在测试中只有java语音编程能够通过,其他均报超时!!!因此我们需要对该算法进行优化处理。

2、单调栈

通过对暴力法求解我们发现,对于后期的计算有大量的重复,因此我们需要来保存之前所计算的内容,在这里我们提出了可以使用栈的方式,每次只需要利用栈顶元素和当前元素来计算面积。

单调栈的定义:栈内的所有元素按照一定的顺序排列,单调栈包括单调递增栈和单调递减栈,顾名思义,栈内元素递增(递减)顺序存放为单调递增(递减)栈。

具体的算法思路:

在原数组的首尾各插入一个0,以此保证栈的完全运行。
逐个遍历数组的元素,若当前元素>=栈顶元素则入栈。
否则就执行以下操作:
弹出栈顶元素,获取下一个栈顶元素 a a a a a a和当前元素的下标差作为宽,弹出的栈顶元素为高,计算面积,并与当前的最大面积相比较。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        //  单调栈
        int n = heights.size();
        int max_s = 0;
        stack<pair<int,int>> increase_st;
        heights.push_back(0);
        heights.insert(heights.begin(),0);
        pair<int,int> a;
        a.first = 0;
        a.second = 0;
        increase_st.push(a);
        for(int i = 1;i<=n+1;i++){
            pair<int,int> top = increase_st.top();
            while(top.second>heights[i]){
                increase_st.pop();
                int temp_heigth = top.second;
                top = increase_st.top();
                max_s = max(max_s,temp_heigth*(i-top.first-1));
                
            }
            pair<int,int> temp;
            temp.first = i;
            temp.second = heights[i];
            increase_st.push(temp);
        }
        return max_s;
    }
};

在使用单调栈后,算法的时间复杂度为 O ( n ) O(n) O(n),性能大大提高,正是借助了栈这一数据结构,使得算法更好的优化。在求解问题中,我们通常最先考虑使用的仍然是暴力法,但是由于暴力法的时间复杂度问题,这就不得不要求我们考虑优化方案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yozu_Roo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值