84. Largest Rectangle in Histogram

#84. Largest Rectangle in Histogram(求矩形最大面积)

题目来源:

https://leetcode.com/problems/largest-rectangle-in-histogram/description/

题意分析:

给一个正整数列表,每个数字x在直方图上表示宽度为1的矩形的高度,求直方图中的最大矩形。

84. Largest Rectangle in Histogram_第1张图片

 

题目思路:

最大矩形的高是由组成矩形的小矩形的最小高度决定的,对于列表[x1,x2,x3,...],每个x都有可能是最大矩形的最小高度,对于这个x,高度确定了,只要求出最大宽度就可以求解。所以问题可以转化为求以x为轴,左右边第一个比x小的值的下标。然后最大矩形就是所有x求出的矩形的最大项。

class Solution {
public:
    int largestRectangleArea(vector& heights) {
        int left,right;
        int res=0;
        for (int i=0; i=0&&heights[left]>=heights[i])
                left--;
            while(right=heights[i])
                right++;
            res=res>(right-left+1)*heights[i]?res:(right-left-1)*heights[i];
        }
        return res;
        
    }
};

上述解法的时间复杂度是O(n^2),提交后超时了,那么只能想O(n)或者O(nlogn)的算法了。我们会发现大部分的时间都用在了求left跟right上,我们可以用一个栈s来优化这一过程。

求right的思路如下,s保存的是没有求到right值的值的列表下标,开始为空。从左到右遍历列表,如果s空或者heights[s.top()]<=heights[i],即当前的高度不小于s栈顶高度的话,把当前高度的下标推进s。如果heights[s.top()]>heights[i],当前的高度比s栈顶高度要小,那么i就是前面那些比heights[i]大且没求到right值的值的right值,弹出s中所有比heights[i]大的值并把right值设为i,然后再把i推进s。

class Solution {
public:
    int largestRectangleArea(vector& heights) {
        // heights.push_back(0);
        vector left(heights.size(),-1);
        vector right(heights.size(),heights.size());
        stack s;
        // s.push(0);
        for (int i=0; i0&&heights[i]();
        //s.push(0);
        for (int i=heights.size()-1; i>=0; i--){
            while (s.size()>0&&heights[i](right[i]-left[i]-1)*heights[i]?res:(right[i]-left[i]-1)*heights[i];
        }
        return res;
        
    }
};

这一解法时间复杂度为O(n),因为对于每个i,right[i],left[i]只计算了一次。提交后A了,但时间长到看不到百分号。

我们观察栈s,如果把它里面的坐标i映射到heights[i],那么它是有序的,栈底到栈顶heights由小到大,而且在不断push,pop的过程中依然能保持,那么我们在求到栈顶元素的right值时,如果把栈顶元素pop出来,剩下的栈顶元素就是就是左边第一个heights比开始栈顶元素的heights小的下标,那么我们在求right的时候就可以求出left已经矩形面积了。

class Solution{
public:
    int largestRectangleArea(vector& heights) {
        int len = heights.size();
        // heights.push_back(0);
        stack s;
        // s.push(0);
        int ans = 0;
        for(int i = 0; i < len; i ++)
        {
            while(! s.empty() && heights[i] < heights[s.top()])
            {
                int index = s.top();
                s.pop();
                ans = max(ans, heights[index]*(i-1-(s.empty()?-1:s.top())));
            };
            s.push(i);
        };
        while(s.size()>0){
            int index = s.top();
            s.pop();
            ans = max(ans, heights[index]*(len-1-(s.empty()?-1:s.top())));
        }
        return ans;
    }
};

84. Largest Rectangle in Histogram_第2张图片


你可能感兴趣的:(Leetcode)