Largest Rectangle in Histogram

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.


Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].


The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given height = [2,1,5,6,2,3],
return 10.

题目分析:

题意非常清楚,就是寻找直方图中的最大矩形面积。

看似非常简单,最先想到的方法就是穷举法,从头开始往后寻找,或者通过剪枝确定可能的右边界向前寻找,时间复杂度O(n2)。这个算法显然在数据很多或者递增递减的图中会挂掉。

根据助教的提示,下面考虑使用栈:

  通过观察可以发现,矩形一定在夹在两个较小的矩形的中间,而且一定有矩形右边的元素高度小于矩形最左端的元素的高度,例如上图中高度2小于矩形最左端高度5。

也就是说计算的矩形一定是一个类似”波峰“的形状。

从而我们可以从头遍历集合,当遇到大于当前栈顶元素高度的元素时,进栈;否则,依次出栈,直到栈顶小于等于当前高度,计算面积。并将当前元素压入栈内。

此解法的核心思想为:一次性计算连续递增的区间的最大面积,并且考虑完成这个区间之后,考虑其前、后区间的时候,不会受到任何影响。也就是这个连续递增区间的最小高度大于等于其前、后区间。

代码如下:

class Solution 
{
public:
    int largestRectangleArea(vector<int>& height) 
    {
        stack<int> index_height;
        height.push_back(0);        //加入立柱0,作为结尾判断
        int area = 0;
        for (int i = 0; i < height.size(); i++)
        {
            if (index_height.empty() || (!index_height.empty() && height[i] >= height[index_height.top()]))
                //如果比栈顶的高度大,则进栈,构建单调栈
                index_height.push(i);
            else
            {
                //比栈顶的高度小,开始依次出栈,并记录下标
                while (!index_height.empty() && height[index_height.top()] > height[i])
                {
                    int index = index_height.top(); 
                    index_height.pop();
                    int width = index_height.empty() ? i : (i - index_height.top() - 1);
                    //计算弹出的面积
                    area = max(area, height[index] * width);
                }
                index_height.push(i);  // 将当前进栈
            }
        }
        return area;

    }
};

提交到OJ,可以AC通过。但发现普遍C语言的程序速度更快,想了好久,以为有什么更好地方法。后来想到,C语言里没有用栈,直接顺序存储的数组访问起来更加快。 0.0

 此博客中的内容均为原创或来自网络,不用做任何商业用途。欢迎与我交流学习,我的邮箱是lsa0924@163.com

原文地址:https://www.cnblogs.com/Jueis-lishuang/p/4960229.html