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

    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].
    
    ![](https://images2018.cnblogs.com/blog/864046/201804/864046-20180410194946191-934507527.png)
    
    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^2个子数组,找最低高度是O(n)的操作,所以复杂度是O(n^3)。

    进一步,可以从每一个bar往两边走,以自己的高度为标准,直到两边低于自己的高度为止,然后用自己的高度乘以两边走的宽度得到矩阵面积。因为对于任意一个bar都计算了以自己为目标高度的最大矩阵,所以最好的结果一定会被取到。每次往两边走的复杂度是O(n),总共有n个bar,所以时间复杂度是O(n^2)。

    最后说说最优的解法,思路跟Longest Valid Parentheses类似,主要维护一个栈,这个栈从低向上的高度是依次递增的。如果遇到当前bar高度比栈顶元素低,那么就出栈直到栈顶元素低于当前bar,出栈过程中检测前面满足条件的矩阵:

    如果栈已经为空,说明到目前为止所有元素(当前下标元素除外)都比出栈元素高度要大(否则栈中肯定还有元素),所以矩阵面积就是高度乘以当前下标i。
    如果栈不为空,那么就是从当前栈顶元素的下一个到当前下标的元素之间都比出栈元素高度大(因为栈顶元素第一个比当前出栈元素小的),所以矩阵面积就是高度乘以当前下标i减栈顶元素再减1。
    

    注意最后还要对剩下的栈做清空并且判断,因为每次是对于前面的元素面积进行判断,所以循环结束中如果栈中仍有元素,还是要继续判断面积直到栈为空。

    时间复杂度:O(n)

    空间复杂度:O(1)

    
    // 84. Largest Rectangle in Histogram
    class Solution_84 {
    public:
    	int largestRectangleArea(vector<int>& heights) {
    
    		int res = 0;
    		stack<int> st; //存储递增的下标
    		for (int i = 0; i < heights.size();i++)
    		{
    			while (!st.empty() && heights[st.top()]>heights[i]) //出栈操作,之前都是递增的
    			{
    				int h = heights[st.top()];
    				st.pop();
    
    				if (st.empty())
    				{
    					res = max(res, h*i);
    				}
    				else
    				{
    					res = max(res, h*(i - st.top()-1)); //当前区间[st.top+1,i-1]
    				}
    				
    			}
    			st.push(i);
    		}
    
    		while (!st.empty()) //递增的
    		{
    			int h = heights[st.top()];
    			st.pop();
    			int s = h * (st.empty() ? heights.size() : (heights.size() - st.top() - 1));
    			res = max(res, s);
    		}
    
    		return res;
    	}
    };
    
    

    题目来源

  • 相关阅读:
    c++中的length,strlen;静态数据成员,静态局部变量
    c++中*的含义
    (1)引用的解释; (2)类的成员函数在类外实现的情况
    DbFunctions 作为 LINQ to Entities 查询的一部分使用时,此方法调用规范 CreateDateTime EDM 函数以创建新的 DateTime 对象。
    年视图,选择月份 ---bootstrap datepicker
    时间控件,页面刷新初始化时间控件只显示年月
    load加载层
    response 下载文件火狐浏览器文件名乱码问题
    Web Uploader
    layer是一款近年来备受青睐的web弹层组件
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/8782103.html
Copyright © 2011-2022 走看看