题意理解
给定一个数组,计算数组框起来的最大面积。
问题分析
用单调栈,控制出入栈。
栈中存放当前元素的索引值(用于计算面积),若递增,当前元素索引入栈,若递减,出栈栈顶元素(是一个索引),计算前一个索引和当前索引的差值,再乘上栈顶索引对应的元素值得到最大面积。直到栈顶元素小于当前元素。 最后再将当前元素索引入栈。
其他
思想神奇。单调栈的记忆功能,选择性记忆
https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
链接
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0); //补一个0,支持最后清栈
int len = heights.size();
stack<int> st;
int area = 0;
for (int i = 0; i != heights.size(); i ++) { //遍历数组
while (!st.empty() && heights[i] < heights[st.top()]) { //找到非递增的第一个元素
int h = heights[st.top()]; //取出栈顶对应的高度
st.pop(); //弹栈
int idx = 0;
if (!st.empty()) { //栈不空
idx = st.top(); //取元素
}
else {
idx = -1; //栈空,设置为-1
}
area = max (area, h * (i - idx - 1)); //计算索引差值,得到最大面积
}
st.push(i); //入栈
}
return area;
}
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int len = heights.size();
if (len == 0) {
return 0;
}
stack<int> my_stack; //存放序号 单调栈 递增栈
vector<int> lefts; //存放序号
for (int i = 0; i < heights.size(); i++) {
//找到最左边的高度边界
while(!my_stack.empty() && heights[i] <= heights[my_stack.top()]) {
my_stack.pop();
}
lefts.push_back(my_stack.empty() ? -1 : my_stack.top());
my_stack.push(i);
}
/*
for(auto left:lefts) {
cout << left << '\t';
}
cout << endl;
*/
//stack<int> my_stack; //存放序号
while(!my_stack.empty()) {
my_stack.pop();
}
vector<int> rights(len); //存放序号
for (int i = len-1; i >= 0 ; i--) {
//找到最右边的高度
while(!my_stack.empty() && heights[i] <= heights[my_stack.top()]) {
my_stack.pop();
}
rights[i] = my_stack.empty() ? len : my_stack.top();
my_stack.push(i);
}
/*
for(auto right:rights) {
cout << right << '\t';
}
cout << endl;
*/
int max_area = INT_MIN;
for (int i = 0; i < len; i++) {
int curr_area = heights[i] * (rights[i] - lefts[i] - 1);
if (max_area < curr_area) {
max_area = curr_area;
}
}
return max_area;
}
};