LeetCode:84. 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.

题目大意就是给出一个柱状图的高度的数组,求出其中能画出的最大矩形的面积。

1.方法一
一个比较简单暴力,容易理解的方法:对于每一个方柱,分别向左向右遍历,到达第一个小于该方柱高度的方柱停止,此时画出了一个以该方柱为最小高度的最大矩形,可以计算出面积:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if (heights.empty())
            return 0;
        int max = 0;
        for (int i = 0; i < heights.size(); ++i) {
            if (heights[i] <= max/heights.size()) continue;//如果该方柱高度过低,那也没有计算的必要了,略过
            int temp = helper(heights, i);
            if (temp > max)
                max = temp;
        }
        return max;       
    }
private:
    int helper(const vector<int>& heights, int i) {
        if (heights[i] == 0) return 0;
        int l = i, r = i;
        while(l-1 >= 0 && heights[l-1] >= heights[i]) --l;
        while(r+1 < heights.size() && heights[r+1] >= heights[i]) ++r;
        return heights[i] * (r-l+1);
    }
};

2.方法二
解法来源:https://www.geeksforgeeks.org/largest-rectangle-under-histogram/
比较难以理解,但是该方法时间复杂度为O(N),值得思考。
方法是这样的:还是要找出以每个方柱为最低高度的最大矩形,关键就是找出左边第一个小于该高度的和右边第一个小于该高度的。维持一个stack,遍历输入的数组。如果当前遍历的该方柱高度大于等于栈顶的方柱高度,那么就将其压入栈;如果当前遍历的该方柱高度小于栈顶的方柱高度,就一直将栈顶元素弹出,直到该方柱高度大于等于栈顶的方柱高度。对于每个弹出的方柱,计算以它为最低高度的最大矩形的面积,计算的方法:弹出后当前栈顶的方柱是左边第一个小于该高度的方柱,当前遍历的方柱是右边第一个小于该高度的方柱。
这是从左往右遍历的。实际编程中,为了方便,往往在右边放一个高度为0的方柱作为哨兵,然后从右往左遍历。
光看文字描述比较难以理解,需要自己在草稿纸上举一个例子,将整个过程模拟一遍,好好体会一下。
下面是我的代码:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if (heights.empty())
            return 0;
        int max = 0;
        heights.push_back(0);//作为哨兵
        int N = heights.size();
        stack<int> si;
        si.push(N-1);
        for (int i = N-2; i >= 0; --i) {
            if (heights[i] >= heights[si.top()]) {
                si.push(i);
                continue;
            }
            while (heights[si.top()] > heights[i]) {
                int t = si.top();
                si.pop();
                int s = heights[t] * (si.top()-i-1);
                if (s > max)
                    max = s;
            }
            si.push(i);
        }
        while (si.size() > 1) {//遍历结束后,将栈里面残留的元素弹出
            int t = si.top();
            si.pop();
            int s = heights[t] * (si.top()-(-1)-1);
            if (s > max)
                max = s;
        }
        return max;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43462819/article/details/84138770
今日推荐