力扣84.柱状图中最大的矩形及单调栈介绍和用法总结

Posted weixin_43739821

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣84.柱状图中最大的矩形及单调栈介绍和用法总结相关的知识,希望对你有一定的参考价值。

题目:
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4]
输出: 4

提示:
1 <= heights.length <=10^5
0 <= heights[i] <= 10^4

思路:
依题目数据量可知暴力绝对超时,所以想到了用单调栈,单调栈顾名思义就是栈中存储的数据是递增或递减的,用 O(n) 复杂度的一重遍历找到每个元素前后最近的更小/大元素位置,比如本题用的就是递增单调栈。

我们可以以下标i遍历每个高度,并将其下标放入单调栈中,当遇到比栈顶高度大或者相等的下标就进栈,当遇到比它高度小的就一直让栈顶出栈,直到栈顶的高度比遍历到的元素高度下标小或者相等。

那么这么做有什么意义呢,意义在于我们每次弹出栈顶就可以得到这个栈顶元素左右侧离他最近的且高度小于或等于他的下标,当遇到弹出情况,显然i下标是这个栈顶元素右侧第一个高度比它小的,而栈顶元素被弹出后的新的栈顶元素显然又是它左侧第一个高度比它小或者相等的,这样左侧中间原本那些高度大于它的我们就不用管了,因为它之前是栈顶,那么原来那些高度大于它的肯定已经被弹出了,我们只需要记录下标求宽度,这样我们就可以计算这个高度对应的面积。

有人可能会有疑问,如果栈中相邻元素高度相同怎么办,这样每次计算的也不是这个高度对应的最大面积呀!这个不用担心,假设栈顶中现在俩个元素高度相同,我们会首先计算栈顶元素对应的面积,待它弹出后还会计算下一个栈顶元素面积,虽然高度不变,但是我们存储的是下标呀,弹出后我们的矩形高度不变但是长度是在增加的,所以这个方法肯定是可以计算到一个高度的最大面积的,一直求每个高度对应面积取最大值,我们就可以得到答案。

总结:单调栈就是栈中存储的数据是递增或递减的,用 O(n) 复杂度的一重遍历找到每个元素前后最近的更小/大元素位置,当我们读题之后知道需要求一个元素最近的比他大或比他小的元素就需要用到单调栈。

代码:
另外这个题目还有一些值得注意的小细节,比如在末尾添0,在while循环中还要判断栈是否为空,否则会WA,都在注释中写明了。

int largestRectangleArea(vector<int>& heights) //用单调栈求每个高度的面积 O(n)时间复杂度
	heights.push_back(0);//在末尾添一个假数据 防止我们输入的恰好是递增序列的情况 这种情况我们的whie循环不会计算任何一个高度的面积 末尾添一个0可以强制让它计算面积
	int n = heights.size(),sum=0;//sum存结果
	stack<int>ms;//单调栈 非递减栈 只有在遇到比栈顶高度小的元素才会出栈 高度相等也进栈
	for (int i = 0; i < n; i++) 
		while (!ms.empty() && heights[ms.top()] > heights[i]) //计算矩形高度为栈顶元素高度时的面积
			int heigh = heights[ms.top()];//记录栈顶高度
			ms.pop();
			int left;//这个left是刚刚的栈顶的左侧的第一个高度<=它的下标
			if (ms.empty()) left = -1;//用if判断防止刚刚栈顶左侧没有高度<=它的元素 那面积就等同于heigh*i了 所以令left=-1
			else left = ms.top();
			int right = i ;//这个是刚刚栈顶右侧的第一个比它高度低的下标
			sum = max(sum,heigh*(right-left-1));
		
		ms.push(i);//栈存储下标
	
	return sum;

以上是关于力扣84.柱状图中最大的矩形及单调栈介绍和用法总结的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode84. 柱状图中最大的矩形(单调栈)

84. 柱状图中最大的矩形 : 单调栈经典运用题

Leetcode No.84 柱状图中最大的矩形(单调栈)

leetcode84柱状图中最大的矩形单调栈维护

⭐算法入门⭐《栈 - 单调栈》困难01 —— LeetCode 84. 柱状图中最大的矩形

LeetCode84. 柱状图中最大的矩形