(C++)柱形图中最大矩形面积详解 LeetCode 84

题目:

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

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

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

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

示例:

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

题目分析 :

 如果输入为非递减序列,例如输入为{1, 1, 2, 2, 2, 3},那么矩形图为:

那么最大面积就是max(1 * 6,    1 * 5,     2 * 4,    2 * 3,     2 * 2,    3 * 1 )

我们的目的就是构建一个这样的序列,这样就可以很方便的求解,我们利用栈来构建这样一个非递减序列

输入: [2,1,5,6,2,3]
入栈原则:栈为空或者栈顶的元素小于正在处理的数, 如果当前栈顶元素大于正在处理的数,栈顶元素弹出(不停的弹出,直到栈顶元素小于正处理数),再入栈; 最大面积初始值为0

思路如下(编写代码不方便)

step1: 处理数字2,由于栈为空, ---------------栈内元素为{ 2 },面积为0

step2:处理数字1, 当前栈顶元素2大于1, 弹出栈顶元素2,由于把2弹出了,所以我们最后的栈内没有这个元素,所以我们现在就得计算以2为高的最大矩形面积,高度为2, 长度为1(因为2 的后面就是1,1比2小),面积为 2,更新面积;1入栈,由于弹出了一个, 所以入栈两个1 ------------------------栈内元素为{1, 1},面积为2

step3:处理数字5,当前栈顶元素为1, 小于5,5入栈;  ---------------------------栈内元素为{1, 1, 5}, 面积为2

step4:处理数字6,当前栈顶元素为5, 小于6,  6入栈,  -----------------------------栈内元素为{1, 1, 5, 6},面积为2

step5:处理数字2. 当前栈顶元素为6, 大于2,把6弹出,同理处理以6为高的矩形面积,高度为6, 长度为1(6前面的和后面的矩形高度都比6小), 面积为6,更新面积; 栈内元素{1, 1, 5} ,栈顶元素为5,仍然大于2,把5弹出, 处理以5为高的的矩形面积,高为5, 长度为2(5前面的一定比它小,之前弹出了一个6, ), 面积为 5 * 2 = 10, 更新面积,2 入栈,由于弹出两个数,入栈3个2   --------------------------------------------栈内元素为{1,  1,  2, 2, 2}, 面积为 10

step6:处理数字3,当前栈顶元素为2,小于3, 入栈 , -----------------------------栈内元素为{1,  1,  2, 2, 2,  3}, 面积为 10

step7:现在我们得到了前面提到的非递减序列,可以计算面积了

我们可以看到上面的栈内有很多冗余数据,入栈操作麻烦;为了方便编程我们使用数组的下标进行入栈,上面例子最后的栈内元素就是{1, 4, 5}, heights[1] = 1, 其中有 1 - 0 + 1 =  2个1;heights[4] = 2, 其中有 4 - 1 = 3个 2; heights[5] = 3, 其中有5 - 4 = 1个3,(第一个元素的个数特殊处理),可以说栈{1,  1,  2, 2, 2,  3}, 与栈 {1, 4, 5}信息等价,原理介绍完毕,完整代码如下:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        stack<int> index;
        int area = 0;
        //数据入栈与出栈处理
        for(int i = 0; i < n; i++)
        {
            if(index.empty() || heights[index.top()] < heights[i])
            {
                index.push(i);
            }
            else
            {
                while(!index.empty() && heights[index.top()] >= heights[i])
                {
                    int tem = heights[index.top()];
                    index.pop();
                    int len = 0;
                    if(index.empty())
                    {
                        len = i;
                    }
                    else
                    {
                        len = i - index.top() - 1;
                    }
                    area = max(area, len * tem);
                }
                index.push(i);
            }           
        }
        //整体处理
        while(!index.empty())
        {
            int tem = heights[index.top()];
            index.pop();
            int len = 0;
            if(index.empty())
            {
                len = n;
            }
            else
            {
                len = n - index.top() - 1;
            }
            area = max(area, len * tem);
                
        }
        return area;
    }
};

猜你喜欢

转载自blog.csdn.net/qianji_little_boy/article/details/82915145
今日推荐