今天首次通过了力扣上的一道困难题——柱状图中最大的矩形,这道题主要是在运用单调栈,单调栈就是一个单调递增的栈。在这道题让我们求最大的矩形的面积,乍一看好像无从下手,但其实我们知道面积的大小和这里面最低的数有关,他决定了这个矩形的高。那么我们就可以对每一个数,求离它的第一个比他小的数,左右各求一个。那么这之间的距离就是矩形的宽。再比较每个数能构成的最大的矩形,就能得到结果。接下来给出代码:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<int> s1, s2;
vector<vector<int>> area(heights.size(), vector<int>(2, 0));
int m = 0;
for (int i = 0; i < heights.size(); i++) {
while (!s1.empty() && heights[s1.top()] >= heights[i]) {
s1.pop();
}
if (!s1.empty())
area[i][0] = i - s1.top() - 1;
else
area[i][0] = i;
s1.push(i);
}
for (int i = heights.size() - 1; i >= 0; i--) {
while (!s2.empty() && heights[s2.top()] >= heights[i]) {
s2.pop();
}
if (!s2.empty())
area[i][1] = s2.top() - i - 1;
else
area[i][1] = heights.size() - 1 - i;
s2.push(i);
}
for (int i = 0; i < heights.size(); i++) {
if ((area[i][0] + area[i][1] + 1) * heights[i] > m)
m = (area[i][0] + area[i][1] + 1) * heights[i];
}
return m;
}
};
我们先对每一个数从左开始构建单调递增栈,如果栈是空的,说明从左边此时没有比当前数小的数,那么这个矩形就会从最左边开始,如果栈不是空的,那么就说明从左边有一个比当前数小的数,那么矩形得从它开始。对于从右开始的单调栈也是一样的。那么这样我们就得到了两个比当前数小的数,他们的中间就是矩形的宽,与高乘起来再比较每个数的矩形,就能得到最大矩形。