84、给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
思路:找到每个柱子 左右两边第一个小于它的柱子 的 下标。左侧第一个小于它的柱子的下标右侧一个即第一个大于它的高度的下标,同理右侧。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int nh=heights.size(); int ans=0;
vector<int> left(nh,-1);vector<int> right(nh,nh);
vector<int> st;
for(int i=0;i<nh;i++)
{
if(st.size()==0) st.push_back(i);
else {
if(heights[st[st.size()-1]]<heights[i])
{
left[i]=st[st.size()-1];
st.push_back(i);
}
else
{
while((st.size()>0)&&(heights[st[st.size()-1]]>=heights[i]))
{
st.pop_back();
}
if(st.size()>0) left[i]=st[st.size()-1];
st.push_back(i);
}
}
}
st.clear();
for(int i=nh-1;i>=0;i--)
{
if(st.size()==0) st.push_back(i);
else {
if(heights[st[st.size()-1]]<heights[i])
{
right[i]=st[st.size()-1];
st.push_back(i);
}
else
{
while((st.size()>0)&&(heights[st[st.size()-1]]>=heights[i]))
{
st.pop_back();
}
if(st.size()>0) right[i]=st[st.size()-1];
st.push_back(i);
}
}
}
for(int i=0;i<nh;i++)
{
ans=max(ans,heights[i]*(right[i]-left[i]-1));
}
return ans;
}
};
我看到84题就想到了42、接雨水:
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
思路是相似的,但是这个是记录一个柱子 左右侧最高的柱子的高度。
class Solution {
public:
int trap(vector<int>& height) {
int n=height.size(); int ans=0;
vector<int> left(n+1,0);vector<int> right(n+1,0);
for(int i=1;i<n;i++)
{
left[i]=max(left[i-1],height[i-1]);
}
for(int j=n-2;j>=0;j--)
{
right[j]=max(right[j+1],height[j+1]);
}
for(int i=1;i<n-1;i++)
{
int mh=min(left[i],right[i]);
if(mh>height[i]) ans+=mh-height[i];
}
return ans;
}
};