单调栈 及 应用 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驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2021-01-13 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 双指针
2021-01-13 LeetCode 剑指 Offer 61. 扑克牌中的顺子 模拟
2021-01-13 LeetCode 1689. 十-二进制数的最少数目 模拟 观察规律