您的位置:首页 > 编程语言 > C语言/C++

[leetcode-84]Largest Rectangle in Histogram(c++)

2015-08-09 17:29 791 查看
问题描述:原题链接

分析:我之前做过这道题,但是无意间看到网上的一种做法,实在是拍案叫绝,爱不释手,第一个发明这个解法的大神,请收下我的膝盖。

这道题很明显是用栈的结构,但是这里面有几个小问题,就是怎么确定柱的边界。这里是指左右延伸的边界,我的做法太丑就不赘述了,它的做法是维护一个栈,一个高度值从低到高的栈(而且维护的是索引)。那么当某个元素要出栈时,那么高度自然就是该元素本身的高度。

那么讨论宽度,因为栈维护的是一个单调递增的一个索引序列,所以我们可以肯定,当前出栈元素的前一个元素的值一定小于当前值,但是在height数组里面,前一个元素的下一个元素一定大于或等于当前值。这样左边界就找到了。(stack.top()+1),那右边界呢?同理,既然要出栈,当前比较的元素一定小于当前待出栈元素,那么当前比较元素的前一个一定大于(如果小于,早就出栈了)。那么右边界也就确定了:i-1。这样整个的宽度就是:(i-1)-(stack.top()+1)+1 = i-stack.top()-1;慢着,有bug,stack.top(),如果是空的呢?如果是空的,相当于,当前元素是从0到i这些元素中的最小值。那么左边界自然就是0,右边界为i-1,宽度为i了。

另外,一个让我觉得特别牛叉的地方就是:一般当用栈进行完之后,就退出了循环,然后再while(!stack.empty()),再来一遍。但是这位大牛,事先向height中添加了一个最小值0,这样当进行到最后一个时,栈中所有的元素都会弹出。这样就没有了外层的while循环。(赞赞赞)

代码如下:24ms

[code]class Solution {
public:
    int largestRectangleArea(vector<int>& height) {
        height.push_back(0);
        int length = height.size();
        stack<int> stack;

        int max = 0;
        int i = 0;

        while(i<length){
            if(stack.empty()||height[stack.top()] < height[i]){
                stack.push(i++);
            }else{
                int index = stack.top();
                stack.pop();
                int area = height[index]*(stack.empty()?i:i-stack.top()-1);
                if(area>max)
                    max = area;
            }
        }
        return max;
    }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: