LeetCode 84. Largest Rectangle in Histogram
题目
Given an array of integers heights
representing the histogram’s bar height where the width of each bar is 1
, return the area of the largest rectangle in the histogram.
翻译
给定一个整数数组heights
,表示柱状图的高度,每个柱子的宽度为1
,返回柱状图中最大矩形的面积。
解析
这道题目的解法是单调栈,单调栈的思路是,维护一个单调递减的栈,当遇到比栈顶元素小的元素时,就计算栈顶元素的面积,然后弹出栈顶元素,直到栈顶元素大于等于当前元素,然后将当前元素入栈。
选用单调栈的原因
这道题目的解法是单调栈,这里介绍一下为什么选用单调栈。
因为计算柱状图中最大矩形的面积,需要计算每个柱子的左边界和右边界,然后计算面积,这里的左边界和右边界都是指比当前柱子小的柱子,所以可以使用单调栈来计算左边界和右边界。
计算右边界
计算右边界的时候,需要从左往右遍历,遍历到的柱子如果比栈顶元素小,当前柱子就是栈顶元素的右边界,然后弹出栈顶元素,直到栈顶元素小于等于当前元素,然后将当前元素入栈。
计算右边界
因为使用的是递减栈,所以栈中的元素是单调递减的,所以栈中的元素的左边界就是栈顶元素的下一个元素,如果栈为空,说明当前元素是最小的元素,左边界就是-1。
计算面积
计算面积的时候,需要计算当前柱子的高度和左边界和右边界的距离,然后计算面积,最后取最大值。
代码
Java
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
int[] left = new int[n];
int[] right = new int[n];
Deque<Integer> stack = new LinkedList<>();
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
stack.pop();
}
left[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
stack.clear();
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
stack.pop();
}
right[i] = stack.isEmpty() ? n : stack.peek();
stack.push(i);
}
int ans = 0;
for (int i = 0; i < n; i++) {
ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);
}
return ans;
}
}
C++
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
vector<int> left(n), right(n, n);
stack<int> mono_stack;
for (int i = 0; i < n; ++i) {
while (!mono_stack.empty() && heights[mono_stack.top()] >= heights[i]) {
right[mono_stack.top()] = i;
mono_stack.pop();
}
left[i] = (mono_stack.empty() ? -1 : mono_stack.top());
mono_stack.push(i);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans = max(ans, (right[i] - left[i] - 1) * heights[i]);
}
return ans;
}
};