84柱状图的最大矩形(重点单调栈解法)

题目描述

在这里插入图片描述

暴力解法宽(自己写)通过率88/96

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int L = heights.size();
        vector<int> dp(L,0);
        int res = INT_MIN;
        int flag = 0;
        for (int i = 0; i < L; i++)
        {
            if (heights[i] != 0)
            {
                if (i == 0)
                    dp[i] = 1;
                else
                    dp[i] = dp[i - 1] + 1;
            }
 
                //dp[i] = ((i == 0) ? 0 : dp[i - 1]) + 1;
        }
        for (int i = 0; i < L; i++)
        {
            int H = INT_MAX;
            int area = 0;
            if (heights[i] == 0)
            {
                flag = i;
                //continue;
            }
            for (int j = i; j < L; j++)
            {
                H = min(H, heights[j]);
                int W = j - i + 1;
                area = max(area, H * W);
            }
            res = max(area, res);
        }
        return res;
    }
};

暴力解法宽(官解)88/96

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;
    }
};

虽说与我写的代码时间复杂度一样,但是明显在空间复杂度和代码简洁程度上优于我的代码;我在考虑矩形的底边长的时候,用一个dp数组记录,在第i个矩形以前连续矩形的数量,这是以为我先做了85题,然后做84题的时候形成了固定思维,起始那段求dp数组的代码可以直接删掉。其他的话与官解一致;

暴力解枚举高 89/96

枚举高复杂度最差为O(n2),枚举宽根据 上边代码所写是实打实的O (n2);
对于枚举枚举宽,就算是加上剪枝(在第二层循环中,如果对应列高为0,就直接跳出循环见下边代码);第88个案例仍旧不能成功,原因在于第88个案例输入数组中没有0元素。但是加上剪枝以后时间复杂度上在遇到有零元素的输入时,时间复杂度会降低的;枚举高的算法,有点2分法的意思,所以对于没有零元素的输入仍旧可以保证提高时间效率

 if(heights[right]==0)
 	break;

单调栈

在枚举高的基础上使用单调栈方法来提高时间效率
单调栈是另一块重要的知识,不熟悉或者遗忘的话看这个题解会迷糊;建议去熟悉一下
链接:力扣496下一个更大元素I
链接:力扣503下一个更大元素II

什么是单调栈以及用途
单调栈实际上就是栈,只是限制要比普通的栈更严格而已了。要求是每次入栈的元素必须要有序(如果新元素入栈不符合要求,则将之前的元素出栈,直到符合要求再入栈),使之形成单调递增/单调递减的一个栈。
单调递增栈:只有比栈顶小的才能入栈,否则就把栈顶出栈后,再入栈。出栈时可能会有一些计算。适用于求解第一个大于该位置元素的数。
单调递减栈:与单调递增栈相反。适用于求解第一个小于该位置元素的数。

单调栈用途
单调栈一般用于解决 第一个大于 xxx 或者 第一个小于 xxx 这种题目

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int L = heights.size();
        int ret = INT_MIN;
        vector<int> left(L);//left[4]表达第四根柱子左侧第一个小于它得主柱子索引
        vector<int> right(L);//right[4]表达第四根柱子右侧第一个小于它得主柱子索引
        //如果右侧没有比其大得柱子,那么记为L
        //如果左侧没有比其小的柱子,记为0
        stack<int> st_R;
        stack<int> st_L;
        for(int i=L-1;i>=0;i--)
        {
            while(!st_R.empty() && heights[i] <= heights[st_R.top()])
            {
                st_R.pop();
            }
            right[i] = st_R.empty()?L:st_R.top();
            st_R.push(i);
        }

        for(int i=0;i<L;i++)
        {
            while(!st_L.empty() && heights[i] <= heights[st_L.top()])
            {
                st_L.pop();
            }
            left[i] = st_L.empty()?-1:st_L.top();
            st_L.push(i);
        }
        for(int i=0;i<L;i++)
        {
            int width = right[i]-left[i]-1;
            int area = width*heights[i];
            ret = max(area,ret);
        }
        return ret;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

星光技术人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值