码迷,mamicode.com
首页 > 其他好文 > 详细

【leetcode】柱状图中最大的矩形(第二遍)

时间:2020-02-10 10:13:33      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:str   ++   code   height   矩形   amp   位置   tps   ret   

题目链接

【题解】


考虑每个柱子为最高柱子对答案的贡献,就是看这个柱子往左能domain多少个单位
往右能domain多少个单位。
遇到比它小的为止
遍历所有的柱子为最高柱子的情况.
就能够覆盖到所有的矩形了。

也即枚举一个位置然后如果比它高就一直扩展,往左往右各做一次就好。
这样的时间复杂度是O(N^2)的

我们可以维护一个单调递增的队列。
这个队列里面第i个元素和第i-1个元素
假设他们原来在数组里的位置是
ii和jj
显然min(ii+1,jj)..jj这一段里面的柱子都是比i元素也即在原来中的jj位置的柱子
来得高的。
同时单调队列栈顶的元素所在的位置设为kk
jj..kk这一段的柱子显然也是全都高于jj
所以贡献就能算出来了。
(sta[top]-sta[cur-1])*height[sta[cur]];
对于每一个算贡献的cur,显然没必要再往右扩展了。
因为算这个答案的时候,实际上。就是因为遇到了一个比栈顶的元素矮的柱子。
那每个比它高的柱子,刚好就不能再继续往右扩展了。
因此算法是正确的。

这题的关键就在于,想到枚举每个柱子是最高元素,然后往左往右扩展这一步。
从而联想到用单调队列的性质加速这个找左边界和右边界的过程.

【代码】

class Solution {
public:

    int largestRectangleArea(vector<int>& heights) {
        int sta[100000+10];
        int top = 0;
        int ans = 0;
        sta[0] = -1;
        for (int i = 0;i < (int)heights.size();i++){
            if (top==0 || heights[i]>=heights[sta[top]]){
                sta[++top] = i;
            }else{
                while (top>0 && heights[i]<heights[sta[top]]){
                    ans = max(ans,((i-1)-sta[top-1])*heights[sta[top]]);
                    top--;
                }
                sta[++top] = i;
            }
            //             for (int j = 1;j<=top;j++){
            //     cout<<sta[j]<<" ";
            // }
            // cout<<endl;
        }
        while (top>0){
            ans = max(ans,((int)heights.size()-1-sta[top-1])*heights[sta[top]]);
            top--;
        }
        return ans;
    }
};

【leetcode】柱状图中最大的矩形(第二遍)

标签:str   ++   code   height   矩形   amp   位置   tps   ret   

原文地址:https://www.cnblogs.com/AWCXV/p/12289778.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!