单调栈 及 应用 Leetcode 84 柱状图中最大的矩形 举例

单调栈主要用于处理,在连续数据结构中(数组)快速获取比自己大或者小的数字索引。
比如下题中的需求

由于是求左边比当前元素大的最近的元素。
我们使用栈记录之前的数字索引和大小,栈顶是离当前元素最近的,如果它不符合条件,那么我们接下来只需要继续向左检测,且检测比已经检测的元素更大的元素(某个元素不符合条件,小于等于它的元素无须检测)。那么这个栈排除了过小的元素,栈里的元素肯定是从栈顶到栈底,呈现一个单调的趋势,如图

地址 https://leetcode-cn.com/problems/largest-rectangle-in-histogram/

给定 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^2),会超时。
但是如果我们使用单调栈记录每个边左边与右边比当前边最近的短的边,就可以得出它能组成的矩形长度。时间复杂度是O(n)

代码如下

class Solution {
public:
	int largestRectangleArea(vector<int>& heights) {
		stack<int> st;
		int n = heights.size();
		int left[100010]; int right[100010];
		memset(left, -1, sizeof left);
		memset(right, -1, sizeof right);

		for (int i = 0; i < heights.size(); i++) {
			while (!st.empty() && heights[st.top()] >= heights[i]) st.pop();
			if (st.empty()) left[i] = 0;
			else left[i] = st.top()+1;
			st.push(i);
		}
		st = stack<int>();
		for (int i = heights.size() - 1; i >= 0; i--) {
			while (!st.empty() && heights[st.top()] >= heights[i]) st.pop();
			if (st.empty()) right[i] = n -1;
			else right[i] = st.top()-1;
			st.push(i);
		}
		int ans = -1;
		for (int i = 0; i < heights.size(); i++) {
			if (left[i] == -1) left[i] = 0;
			if (right[i] == -1) right[i] = heights.size()-1;
			int  area = heights[i] * (right[i] - left[i]+1);
			ans = max(ans, area);
		}


		return ans;
	}
};

我的视频题解空间

作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/15797327.html