ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode84.柱状图中最大的矩形

2020-01-28 16:41:02  阅读:218  来源: 互联网

标签:leetcode84 cur int res 元素 heights 柱状图 矩形


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

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

在这里插入图片描述

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

在这里插入图片描述

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

完整代码

暴力思想:针对每一组柱状图,求最大矩形,最终得出整个柱状图中的最大矩形

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int res = 0;
        if(heights.size() == 0)
            return res;
        int cur;
        for(int i = 0; i < heights.size(); ++i){
            int min_height = heights[i];
            for(int j = i; j < heights.size(); ++j){
                if(heights[j] < min_height)
                    min_height = heights[j];
                cur = (j - i + 1) * min_height;
                if(cur > res)
                    res = cur;
            }
        }
        return res;
    }
};

分治

  • 求当前状态下的最大矩形,最小高度左边的最大矩形,最小高度右面的最大矩形
  • 递归运算,取其中的最大值
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if(heights.size() == 0)
            return 0;
        return large(heights, 0, heights.size() - 1);
    }
private:
    int large(vector<int>& heights, int left, int right){
        int min_height = left;
        if(left > right)//递归终止条件
            return 0;
        int i = left + 1;
        while(i <= right){
            if(heights[i] < heights[min_height])
                min_height = i;
            ++i;
        }
        int cur = (right - left + 1) * heights[min_height];
        int l_cur = large(heights, left, min_height - 1);
        int r_cur = large(heights, min_height + 1, right);
        if(cur < l_cur)
            cur = l_cur;
        if(cur < r_cur)
            cur = r_cur;
        return cur;
    }
};


参考:官方题解
leetcode题解

当柱状图是升序的状态时,矩形的高度是最左边的元素,矩形的宽度越宽,矩形的面积越大。或者像【2,1,2】这种情况,矩形的长度是3高度是1。

基本思想:
当前高度的矩形最大面积如何来求?
其实也就是确定矩形的宽度,矩形的宽度为当前高度左面第一个小于当前高度的值和当前高度右面第一个小于当前高度的值之间的宽度为最大宽度

  • 借助栈来保存升序状态的序列
  • 从头开始遍历序列,升序时,元素入栈;一旦出现了降序,停止入栈,来计算矩形的面积
  • 计算矩形的面积:
    依次将栈中的元素出栈,计算以当前出栈元素为高,以当前元素出栈后的栈顶和出现降序时的元素之间作为宽(解释:当前元素出栈后的栈顶是当前元素左面第一个比当前元素小的元素,出现降序时的元素是当前元素右面第一个比当前元素小的元素),来求矩形的面积。
    特别提醒:当栈中只有一个元素时,需要考虑以该元素作为矩形的高,矩形的宽是从第一个元素开始到该元素之间的宽度。

程序说明:

  • 为了便于处理以矩阵中最后一个元素作为矩形的高的情况,我们在原序列的基础上添加一个元素0(0不影响最终结果,以为只当前列高是0)
  • 为了便于处理当栈中只有一个元素时,以该元素作为矩形的高,矩形的宽是从第一个元素到该位置,初始时将-1(-1作为下标0之前的一个下标)入栈
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if(heights.size() == 0)
            return 0;
        stack<int> st;//用来存放当前柱的下标
        int res = 0, cur;
        st.push(-1);// 便于处理以第一个元素作为矩形面积一部分的情况
        heights.push_back(0);//便于处理以最后一个元素作为矩形面积一部分的情况
        for(int i = 0; i < heights.size(); ++i){            
                while(st.top() != -1 && heights[i] < heights[st.top()]){
                    int j = st.top();
                    st.pop();
                    cur = heights[j] * (i - st.top() - 1);//宽度为当前不满足升序情况的元素和出栈元素的上一个元素之间的宽度
                    if(cur > res)
                        res = cur;
                }
                st.push(i);            
        }
        
        return res;
    }
};
qq_31672701 发布了222 篇原创文章 · 获赞 9 · 访问量 3万+ 私信 关注

标签:leetcode84,cur,int,res,元素,heights,柱状图,矩形
来源: https://blog.csdn.net/qq_31672701/article/details/104097597

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有