题意:给出若干柱状图,求其中形成的最大的矩形的面积;
传送门
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
题解:单调栈,枚举每根柱子左边第一根比它矮和右边第一根比它矮的柱子的下标,用单调递增的栈来维护这个下标
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
stack<int> id;
vector<int> left(n);
for (int i = 0; i < n; ++i) {
while (id.size() && heights[id.top()] >= heights[i])
id.pop();
if (id.empty()) left[i] = -1;
else left[i] = id.top();
id.push(i);
}
id = stack<int>();
vector<int> right(n);
for (int i = n-1; i >= 0; --i) {
while (id.size() && heights[id.top()] >= heights[i])
id.pop();
if (id.empty()) right[i] = n;
else right[i] = id.top();
id.push(i);
}
int ret = 0;
for (int i = 0; i < n; ++i) {
ret = max(ret, (right[i]-left[i]-1) * heights[i]);
}
return ret;
}
当一根柱子出栈时,说明它遇到了比它矮的柱子,所以这个时候可以直接标记right,一轮遍历即可。
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
vector<int> left(n), right(n, n);
stack<int> id;
for (int i = 0; i < n; ++i) {
while (!id.empty() && heights[id.top()] >= heights[i]) {
right[id.top()] = i;
id.pop();
}
if (id.empty()) left[i] = -1;
else left[i] = id.top();
id.push(i);
}
int ret = 0;
for (int i = 0; i < n; ++i) {
ret = max(ret, (right[i]-left[i]-1) * heights[i]);
}
return ret;
}