zoukankan      html  css  js  c++  java
  • [LeetCode 84.] 柱状图中最大的矩形

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

    题目描述

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

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


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


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

    示例:

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

    解题思路

    这道题看起来没有接雨水的实际应用场景那么强,唯一的应用例子是楼房安装广告牌。

    最直观的解题思路依旧是暴力解法,遍历没一个柱子,然后左右拓展,直到小于当前柱子高度。暴力解法的时间复杂度是O(N^2)。
    不同于接雨水,这道题没有很好的通过记录“状态”来压缩实践复杂度的方法。

    单调栈

    解决办法是单调栈。入栈 —— 保存状态;出栈 —— 计算收益。

    与接雨水相比,不同点在于出入栈的触发条件上:

    • 接雨水是新条形更高,会触发水位上涨,因而出栈。导致保存状态的单调栈是单调递减的。
    • 最大矩形是新条形更低,会阻断矩形扩展,因而出栈。导致保存状态的单调栈是单调递增的。

    相同之处在于,二者触发条件时,会从栈顶一直向前触发,直到不满足触发条件为止,从而维护了栈的单调性质。

    参考代码

    /*
     * @lc app=leetcode id=84 lang=cpp
     *
     * [84] Largest Rectangle in Histogram
     */
    
    // @lc code=start
    class Solution {
    public:
        int largestRectangleArea(vector<int>& heights) {
            int res = 0;
            heights.push_back(0); // 插入哨兵,用于最后清空队列
            deque<int> q;
            for (int i=0; i<heights.size(); i++) {
                while (!q.empty() && heights[i] < heights[q.back()]) {
                    // res = std::max(res, (i-q.back())*heights[q.back()]);
                    // q.pop_back();
                    int h = heights[q.back()];
                    q.pop_back();
                    int w = q.empty() ? i : (i - q.back() - 1);
                    res = std::max(res, w * h);
                }
                q.push_back(i);
            }
            return res;
        }
    };
    // @lc code=end
    

    单调栈其他题目

  • 相关阅读:
    ehcache 2.4 即将发布,亮点多多
    2010 年个人回忆与总结
    ehcache 2.4 即将发布,亮点多多
    JBoss Seam 3.0.0.Beta1 发布
    JBoss Seam 3.0.0.Beta1 发布
    jQuery 1.5 正式版如期发布
    jQuery 1.5 正式版如期发布
    Contracts for Java
    2010 年个人回忆与总结
    Contracts for Java
  • 原文地址:https://www.cnblogs.com/zhcpku/p/14451217.html
Copyright © 2011-2022 走看看