zoukankan      html  css  js  c++  java
  • 【leetcode】柱状图中最大的矩形(第二遍)

    题目链接

    【题解】

    考虑每个柱子为最高柱子对答案的贡献,就是看这个柱子往左能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;
        }
    };
    
  • 相关阅读:
    常用颜色代码 (30种)
    C++ 调用lib 和 dll的 方法 及 动态库DLL与静态库lib的区别
    如何: 通过HTML文档对象模型访问文档中的ActiveX控件的属性 .
    理解预编译头
    #ifndef用法总结 .
    C++中MessageBox()的详细用法
    如何用Javascript捕获ActiveX对象的事件
    ActiveX控件调用JavaScript函数的方法
    MFC Activex与JavaScript的接口交互
    include包含文件查找的顺序 .
  • 原文地址:https://www.cnblogs.com/AWCXV/p/12289778.html
Copyright © 2011-2022 走看看