LeetCode 84柱状图中最大矩形Hard
-
题目简述:给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。
-
输入:heights = [2,1,5,6,2,3] 输出:10
-
思路:单调栈O(n)
-
找到每个柱子左边和右边离自己最近的比自己低的柱子,夹在中间的矩形面积就为所求,然后用矩形宽度乘以当前柱子高度作为备选答案。即找两边第一个小于它的值
-
维护单调栈,如果当前元素下标
i
对应的柱子高度比栈顶元素对应的柱子高度低,则当前栈顶元素cur
出栈并以此元素为高度计算面积。出栈后,cur
右边第一个比它低的柱子就是i
,左边第一个比它低的柱子高度就是当前栈的栈顶元素top
对应高度。不断出栈直到栈为空或者柱形条i
不再比top
低。出栈后宽度计算:
rihgt = i - 1, left = top + 1, d = right -left + 1 = i - top -1
-
加入栈中元素,保证栈中的元素从栈底到栈顶依次递增,求取面积时按照柱子从高到低的顺序求取
-
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(-1);//在数组末尾添加高度 -1,使得能入栈中的数字都能出栈。
int res = 0;
stack<int> st;
for(int i = 0; i < heights.size(); i++)
{
while(!st.empty() && heights[i] < heights[st.top()])
{
int cur = heights[st.top()];
st.pop();
if(st.empty())
res = max(res, cur * i);
else
res = max(res, cur * (i - st.top() - 1));
}
st.push(i);
}
return res;
}
};
- 写法二:原始数组首尾都添加哨兵,在循环中减少单调栈判空,保证原始数组中的每个元素两边都有比自己小的元素,也就保证了加入单调栈中的所有原始数组元素都能出栈,都可以计算答案。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.insert(heights.begin(), -1);
heights.insert(heights.end(), -1);
int res = 0;
stack<int> st;
for(int i = 0; i < heights.size(); i++)
{
while(!st.empty() && heights[i] < heights[st.top()])
{
int cur = heights[st.top()];
st.pop();
//int r = i - 1, l = st.top() + 1, d = r - l;
res = max(res, cur * (i - st.top() - 1));
}
st.push(i);
}
return res;
}
};
类似题目的单调栈解法:LeetCode 42接雨水