输入: 一个非负整数数组 heights,表示柱状图中各个柱子的高度。每个柱子的宽度为 1。
要求: 求在该柱状图中,能够勾勒出来的最大的矩形面积。
输出: 一个整数,表示最大的矩形面积。
思路:虽然是困难题,但其实是非常标准的单调栈思路,蛮简单的。
目标是找到以数组中每一个高度为高时,能够向右延伸的最大有效宽度,从而计算最大面积。
使用一个单调递增栈来保存柱子的索引。当遍历过程中遇到一个比栈顶元素更小的柱子时,这个更小的柱子就是栈顶元素的右边界。此时,栈顶元素出栈,其高度作为矩形的高。
复杂度:
时间复杂度:O(n)
空间复杂度:O(n)
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
//有点像最小栈 应该是寻找到 下一个比它小的数 然后它本身 乘 到这个小数之间的间隔 就是面积了
//需要每个数都来一遭吗 这样肯定是最稳妥的 但是会出现大量重复计算的过程 如何尽可能减少运算量呢
//对于 [2,1,5,6,2,3]
//2入栈 1来 2必须出栈 2的旅程结束了 所以 2*1 = 2 然后 5入栈 5大于1 1不出栈 然后6 入栈 然后2又来了 2小于6 6的旅程结束6*1= 6
//2 小于 5 5的旅程结束 5*2 = 10 2大于1 1不动 2入栈 然后3来了 然后可以设置一个空节点0 0入栈 全部出栈 这时候呢3*1 = 3 2*2=4 1*5=5
//问题的核心在于出入栈的是序号 比较的是序号代表的值
//所以就是一个很标准的单调栈问题
heights.push_back(0); //最后收尾环节 让所有元素出栈
stack<int> st;
int maxArea = 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 left_boundary;
if (st.empty()) {
left_boundary = -1;
}
else {
left_boundary = st.top();
}
int width = i - left_boundary - 1; //底
maxArea = max(maxArea, h * width);
}
st.push(i);
}
return maxArea;
}
};
6510

被折叠的 条评论
为什么被折叠?



