单调栈-最大矩形

一、引言

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。

来源:力扣(LeetCode)

LeetCode-84. 柱状图中最大的矩形

 

二、单调栈

1、栈中维护数组的下标,栈中下标对应的数组值升序排列。栈中初始化-1结点,起始标记。

 

2、O(n)遍历数组中每个值,对第i个值有两种情况

(1)prev == -1 || heights[i] >= heights[prev]:下标i入栈

    前项表示栈为空,后项表示满足单调性。

 

(2)heights[i] < heights[prev]:出栈

    第i项违反单调性,栈中元素逐个出栈,直到栈顶元素满足单调性。每项出栈时,维护以出栈下标对应高度为高的最大矩形面积,出栈元素为prev,待入栈元素为i:

    矩形高为heights[prev],左边界为栈中prev前一个元素(sta.top()),右边界为(i)。则矩形宽为(i-prev-1)。

 

3、遍历每个数组下标后,得到维护的最大面积,可以在数组最后加高为0的元素,即限制右边界,保障最终栈中元素全部退出。

 

核心思想:

每个下标prev出栈时计算以heights[prev]为高的最大矩形的面积。

可以发现:

该最大矩形的左边界为:栈中prev前一个下标(前一个下标对应的高度小于prev高度)

该最大矩形的右边界为:待入栈下标i(下标i对应的高度小于prev高度)

        并且两个边界之间的下标对应的高度均大于prev高度。无论左右,比它高的下标在判断到它时均已出栈,所以找到的就是左右边界。

(1)左边界-prev间 比prev高的元素,在之前入栈prev时被出栈

(2)prev-右边界间 比prev高的元素,在当前出栈到prev时会被出栈

 

注意:对于连续多个下标的高度相等的情况,下文代码的最大矩形会以最左侧的下标考虑。(左边界找的是小于等于它高度的下标)(修改高度等于的情况可以调整)

 

三、程序代码

int largestRectangleArea(vector<int>& heights)
{
	heights.push_back(0);
	stack<int> sta;
	int ans = 0;
	sta.push(-1);

	for (int i = 0; i < heights.size(); i++)
	{
		int prev = sta.top();
		if (prev == -1 || heights[i] >= heights[prev])	//入栈
		{
			sta.push(i);
		}
		else		// 出栈
		{
			while (prev != -1 && heights[prev] > heights[i])
			{

				sta.pop();
				ans = max(ans, heights[prev] * (i - sta.top() - 1));
				prev = sta.top();
			}
			sta.push(i);
		}
		
	}

	return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值