单调栈在LeetCode上如何解决问题?
摘要:单调栈力扣题(leetcode) 84. 柱状图中最大的矩形 难度:困难 相关标签:栈、数组、单调栈 题目: 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大
单调栈力扣题(leetcode)
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\)
核心知识点:单调栈
单调栈的核心作用:找到每个元素左边 / 右边最近的更小(或更大)元素的下标
本题需解决:对每个柱子,找到其左侧最近的更矮柱子(left [i])和右侧最近的更矮柱子(right [i])
矩形面积计算:\(height[i] × (right[i] - left[i] - 1)\)(宽度为左右边界之间的距离)
解题思路
预处理 \(left\) 数组:\(left [i] = 左侧最近的更矮柱子下标(无则为 - 1)\)
预处理 \(right\)数组:\(right [i] = 右侧最近的更矮柱子下标(无则为 n)\)
遍历每个柱子,计算面积并更新最大值
代码:
class Solution
{
public:
int largestRectangleArea(vector<int>& heights)
{
int n = heights.size();
if (n == 0) return 0;
vector<int> left(n, -1); // 左侧最近更矮柱子下标
vector<int> right(n, n); // 右侧最近更矮柱子下标
stack<int> st; // 存储下标,保持栈内下标对应的高度递增
// 计算left数组
for (int i = 0; i < n; ++i)
{
// 栈不为空且栈顶元素高度≥当前高度 → 弹出(无利用价值)
while (!st.empty() && heights[st.top()] >= heights[i]) st.pop();
if (st.empty()) left[i] = -1;
else left[i] = st.top();
st.push(i);
}
// 清空栈,计算right数组
st = stack<int>(); // 无clear(),重新构造
for (int i = n - 1; i >= 0; --i)
{
while (!st.empty() && heights[st.top()] >= heights[i]) st.pop();
if (st.empty()) right[i] = n;
else right[i] = st.top();
st.push(i);
}
// 计算最大面积
int max_area = 0;
for (int i = 0; i < n; ++i)
{
int area = heights[i] * (right[i] - left[i] - 1);
max_area = max(max_area, area);
}
return max_area;
}
};
相似题目
最大矩形困难
好子数组的最大分数困难
85. 最大矩形
难度:困难
相关标签:栈、数组、动态规划、矩阵、单调栈
题目:
给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
