zoukankan      html  css  js  c++  java
  • leetcode 84. Largest Rectangle in Histogram

    link

    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.

    题意:

    给出条形图,求出其中面积 ,看图片题意很明确。

    思路:

    只能想出来O(N^2)的方法。但是感觉可以优化到O(N),因为有 很多重复步骤。

    于是搜了一下题解。

    简单的来说,我想对于某一个位置i,看以heights[i]为高的矩阵最远可以向左右延伸到哪里。

    在这个子问题上,O(N)的做法自然是往左右扫。但这没有用到上一个位置的信息,简单的说,如果上一个位置比它高,那它能到的地方一定不会比上一个位置近。更玄学一点的,也没有用到前面高度的信息。

    为此,做法是维护一个栈。并保证栈内元素单调递增。

    保证栈内元素单调递增的方法是,每次放进元素前,将大于它的元素退栈。然后再将它放进去。

    这样做的原因是,退完的栈顶一定是< 这个高度的最近的地方。

    那么能延伸到的边界就是栈顶了。

    如果栈为空的话,说明没有一个值比它小,就可以延伸到这个条形图的边界。

    遍历所有元素需要O(N),由于每个元素只入栈一次,因此复杂度还是O(N)

    这样从左往右做一遍,从右往左做一遍,则可以获得一个点到左右的最远距离。然后有了长宽就可以计算了。

    code

    class Solution {
    public:
        int largestRectangleArea(vector<int>& heights) {
            if(heights.size() == 0) return 0;
            stack<int> s;
            int ans = 0;
            vector<int> leftPos(heights.size());
            for(int i = 0; i < heights.size(); i++){
                while(!s.empty() &&  heights[s.top()] >= heights[i]) s.pop();
                if(s.empty()) leftPos[i] = 0; // no one is lower than i
                else leftPos[i] = s.top() + 1; // s.top is first one lower than i, 
                s.push(i);
            }
            while(!s.empty()) s.pop();
            for(int i = heights.size() - 1; i >= 0; i--){
                while(!s.empty() && heights[s.top()] >= heights[i]) s.pop();
                int rightPos = heights.size() - 1;
                if(!s.empty()) rightPos = s.top() - 1;
                int tmp = heights[i] * (rightPos - leftPos[i] + 1);
                ans = max(tmp, ans);
                
                s.push(i);
            }
            return ans;
        }
    };
  • 相关阅读:
    webpack 打包报 ERROR in static/js/vendor.2eff2b5a1d36f4b7f033.js from UglifyJs
    常见重构技巧
    Java常见重构技巧
    Python写基于非线性优化的2D-SLAM系统(已开源)
    分享一个免费开源压缩视频软件!!!【视频压缩后质量还可以】
    AJAX之超时与网络异常处理
    HTTP
    Gin多次读取body
    高效的数据压缩编码方式 Protobuf
    TCP报文之-tcp dup ack 、tcp Out-of-Order
  • 原文地址:https://www.cnblogs.com/bbbbbq/p/7630203.html
Copyright © 2011-2022 走看看