题目
代码(首刷看解析)
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int res = 0;
stack<int> st;
heights.insert(heights.begin(), 0);
heights.push_back(0);
st.push(0); // 第一个元素下标入栈
for(int i = 1; i < heights.size(); i++) {
if(heights[i] > heights[st.top()]) {
st.push(i);
} else if(heights[i] == heights[st.top()]) {
st.pop(); // 这个可以加,可以不加,效果一样,思路不同
st.push(i);
} else {
while(!st.empty() && heights[i] < heights[st.top()]) { // 注意是while
int mid = st.top();
st.pop();
if(!st.empty()) {
int left = st.top();
int right = i;
int w = right - left - 1;
int h = heights[mid];
res = max(res, w * h);
}
}
st.push(i); // 插入元素,同样保证了单调递减栈
}
}
return res;
}
};
代码(7.14 二刷看解析)
单调栈的框架:
stack<int> st;
//此处一般需要给数组最后添加结束标志符,具体下面例题会有详细讲解
for (遍历这个数组)
{
while (栈不为空 && 栈顶元素小于当前元素)
{
栈顶元素出栈;
更新结果;
}
当前数据入栈;
}
这题的巧妙之处在于在数组开头和结尾插入了0,使得操作简单了许多。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<int> stk;
heights.insert(heights.begin(), 0);
heights.push_back(0);
stk.push(0);
int res = 0;
for(int i = 1; i < heights.size(); i++) {
if(stk.empty() || heights[i] >= heights[stk.top()]) {
stk.push(i);
} else {
while(heights[i] < heights[stk.top()]) {
int mid = stk.top();
stk.pop();
if(!stk.empty()) {
int r = stk.top();
int w = i - r - 1;
res = max(res, w * heights[mid]);
}
}
stk.push(i); // 保证单调
}
}
return res;
}
};
代码(9.22 三刷自解)
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.insert(heights.begin(), 0);
heights.push_back(0);
stack<int> sk;
sk.push(0);
int ans = 0;
for(int i = 1; i < heights.size(); i++) {
while(!sk.empty() && heights[sk.top()] > heights[i]) {
int mid = sk.top();
sk.pop();
int left = sk.top();
ans = max((i-left-1)*heights[mid], ans);
}
sk.push(i);
}
return ans;
}
};