柱状图中最大矩形
题目来源
题意:给出一个柱状图,求这个柱状图上可画出的最大矩形的面积
思路一:求出每个柱左右两边的第一个比它低的柱的下标
设第i个柱左边第一个比它低的柱的下标为left[i]
设第i个柱右边第一个比它低的柱的下标为right[i]
则第i个柱向两边扩展的最大矩阵的面积为s[i]=(right[i]-left[i])*height[i];
时间复杂度为O(n*n)
代码如下:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n=heights.size();
vector<int> left(n+5);
vector<int> right(n+5);
for(int i=0;i<n;i++){
int t=i-1;
while(t>=0&&heights[t]>=heights[i])t=left[t];
left[i]=t;
}
for(int i=n-1;i>=0;i--){
int t=i+1;
while(t<n&&heights[t]>=heights[i])t=right[t];
right[i]=t;
}
int s=0;
for(int i=0;i<n;i++){
s=max(s,(right[i]-left[i]-1)*heights[i]);
}
return s;
}
};
思路二:使用一个单调栈,栈中存放每个柱的下标,单调栈中柱的高度从栈底向栈顶单调递增:
若h[top]>h[i]:则h[i]入栈
即以当前柱为左边界可以一直向右拓展。
如遇到比栈顶柱低的柱,即h[top]<=h[i]:则h[top]出栈
则说明无法再往右拓展,则计算矩形面积:
s=(i-stack.top)*stack.top
时间复杂度为O(n)
代码如下:
#include <iostream>
#include<stack>
#include<vector>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int> heights;
int x;
for(int i=0;i<n;i++){
cin>>x;
heights.push_back(x);
}
stack<int> st;
st.push(-1);
int s=0,index=0;
while(!st.empty()){
int top=st.top();
int flag=0;
if(index<n){
if(top==-1||heights[index]>heights[top]){
st.push(index);
index++;
flag=1;
}
}
if(flag==0){
st.pop();
if(st.empty())break;
int j=st.top();
s=max(s,heights[top]*(index-j-1));
}
}
cout<<s<<endl;
return 0;
}