LeetCode: 84. Largest Rectangle in Histogram

LeetCode: 84. Largest Rectangle in Histogram

题目描述

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.

题目大意: 给定 n 个代表在宽度为 1 的矩形条高度的非负整数, 找到它们组成的最大举行的面积。

解题思路

  • 朴素的方法:只需要依次求出以第 i 个矩形条的高度为高,且包含该矩形条的最大矩形的面积 S 。然后取得最大面积,即是所求。分别向左/向右找到所有相邻且高度小于等于当前矩形条的矩形条, 他们组成的以当前矩形条的高度为高的矩形的面积即是 S, 代码描述如下:
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int ans = 0;
        for(int i = 0; i < heights.size(); ++i)
        {
            int left = i, right = i;
            // 向左找到所有相邻且高度小于等于当前矩形条的矩形条
            while(left-1 >= 0 && heights[left-1] >= heights[i]) --left;
            // 向右边找到所有相邻且高度小于等于当前矩形条的矩形条
            while(right+1 < heights.size() && heights[right+1] >= heights[i]) ++right;

            ans = max(ans, heights[i]*(right-left+1));
        }

        return ans;
    }
};
  • 优化: 朴素的方法复杂度为 O(n^2), 会超时(Time Limit Exceeded)。而当我们向左找所有相邻且高度小于等于当前矩形条的矩形条时,实际上可以不用重复计算 left, 而利用之前左边已经求出的结果。

AC 代码

class Solution 
{
public:
    int largestRectangleArea(vector<int>& heights)
    {
        // [startPos[i], endPos[i]]: 表示小于等于 heights[i] 的元素的包含 i 的最大区间
        vector<int> startPos(heights.size(), 0), endPos(heights.size(), heights.size());

        // 求 startPos
        for(size_t i = 1; i < heights.size(); ++i)
        {
            int left = i-1;
            startPos[i] = i;
            while(left >= 0 && heights[i] <= heights[left])
            {
                startPos[i] = startPos[left];
                left = startPos[left] - 1;
            }
        }

        // 求 endPos
        for(int i = heights.size()-1; i >= 0; --i)
        {
            int right = i + 1;
            endPos[i] = i;
            while(right < heights.size() && heights[i] <= heights[right])
            {
                endPos[i] = endPos[right];
                right = endPos[right] + 1;
            }
        }

        int ans = 0;
        for(size_t i = 0; i < heights.size(); ++i)
        {
            ans = max(ans, heights[i]*(endPos[i] - startPos[i] + 1));
        }

        return ans;
    }
};
全部评论

相关推荐

ArisRobert:统一解释一下,第4点的意思是,公司按需通知员工,没被通知到的员工是没法去上班的,所以只要没被通知到,就自动离职。就是一种比较抽象的裁员。
点赞 评论 收藏
分享
我在朝九晚六双休的联想等你:如果我是你,身体素质好我会去参军,然后走士兵计划考研211只需要200多分。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务