leetcode 84. Largest Rectangle in Histogram

来源:互联网 发布:xp系统便签软件 编辑:程序博客网 时间:2024/06/10 21:11

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 heights = [2,1,5,6,2,3],

return 10.

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
      stack<int> st;
        int maxarea=0;
        heights.push_back(0);
        int i=0;
        while(i<heights.size()+1)
        {
            if(st.empty()||heights[st.top()]<heights[i])
            {
                st.push(i);
                i++;
            }
            else
            {
                int t=st.top();
                st.pop();
                maxarea=max(maxarea,heights[t]*(st.empty()?i:i-st.top()-1));
            }
        }
        return maxarea;
    }
};

思路:

首先明白怎么去找这些最大值,无非就是找每个小矩形,然后在其左右两边找比其高的矩形,左边遇到 比它矮的终止,右边遇到比它矮的终止,遍历完0--5后就可以找出最大的矩形了,想法没错,但这样的算法时间复杂度高,所以提供用栈的思路解决。

首先明白栈结构的特点就是有一头是封闭的不能操作,而另一头是可以操作的的。既然我们是想找到矩形左右两边小于该矩形高度的矩形,我们在栈中就按矩形高度升序的索引入栈,当遇到高度小于栈顶索引所对应的高度时也就是我们已经找到了右边界的范围,就是要进行出栈计算其前面的面积,又因为是升序,那旁边的一个不就是左边界。即通过栈的结构形成一个天然的左边界。

思路:这题的一个基本思想是以每一个bar为最低点,向左右遍历直到遇到比他小的bar或边界。这样就能找到一个此bar为最低点的矩形面积。遍历所有的bar之后即可找到最大的矩形面积。但是向左右遍历寻找比他小的bar的时间复杂度是O(n),在加上遍历一遍所有的bar,总的时间复杂度将为O(n*n),是无法通过所有数据的。因此我们需要寻找一种时间复杂度更低的寻找一个bar左右边界的算法。在网上流传了一个设计极其巧妙的方法,借助一个stack可以将时间复杂度降为O(n)。

这种算法的思想是维护一个递增的栈,这个栈保存了元素在数组中的位置。 这样在栈中每一个左边的bar都比本身小,所以左边就天然有界了,也就是左边界就是左边的一个bar。遍历一遍height数组,在将height数组入栈的时候,如果当前元素height[i]比栈顶元素小,则我们又找到了栈顶元素的右边界。因此我们在此时就可以计算以栈顶元素为最低bar的矩形面积了,因为左右边界我们都已经找到了,而且是在O(1)的时间复杂度内找到的。然后就可以将栈顶元素出栈了。这样每出栈一个元素,即计算以此元素为最低点的矩形面积。当最终栈空的时候我们就计算出了以所有bar为最低点的矩形面积。为保证让所有元素都出栈,我们在height数组最后加一个0,因为一个元素要出栈必须要遇到一个比他小的元素,也就是右边界


原创粉丝点击