题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]
。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10
个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10
思路
利用栈将原图转化为递增序列,如将 215623 变为 112223,具体变化方法为:
栈为空时入栈,此时栈中只有 2,第二个数为 1,因为栈顶元素 2 > 1,所以将 2 弹出栈,计算此时最大的面积 2 * 1 = 2 存入 res,将 2 个 1 压入栈中,栈内元素为 [ 1 , 1 ] ,res = 2;
此时 heights[ i ] = 5 和 6,均大于栈顶元素 1,入栈,此时栈内元素为 [ 1 , 1 , 5 , 6 ];
此时 heights[ i ] = 2,因为 6 > 2,6 出栈,res = 6;
同理,5 出栈,res = 5 * 2 = 10(先出栈的一定大);
此时栈顶元素 1 < 2,结束 while 循环,将 3 个 2 压入栈中,栈内元素为 [ 1 , 1 , 2 , 2 , 2 ],res = 10;
此时 heights[ i ] = 3,3 > 2,3 入栈,栈内元素为 [ 1 , 1 , 2 , 2 , 2 , 3 ],res = 10。
对于栈 s,再求该图的最大矩形,与上面的 res 取最大值即可。
代码
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
stack<int> s;
int res = 0;
for(int i=0; i<n; i++){
if(!s.empty() && s.top() > heights[i]){
int len = 0;
while(s.top() > heights[i]){
int temp = s.top();
s.pop();
len++;
res = max(res, len*temp);
//第一个元素出栈后栈为空,会报错
if(s.empty())
break;
}
for(int j=0; j<=len; j++){
s.push(heights[i]);
}
}else{
s.push(heights[i]);
}
}
//以下为对递增序列求最大值
int len = 0;
int k = 0;
while(!s.empty()){
int temp = s.top();
s.pop();
len++;
if(s.empty()){
res = max(res, temp*n);
return res;
}
if(s.top() < temp){
k += len;
res = max(res, temp*k);
len = 0;
}
}
return res;
}
};