题目:
题解:
- 题解1:暴力法,直接从每个矩形开始寻找最大的矩形,时间复杂度O(n)。
- 题解2:分治法,感觉和暴力法思路一样,不过是利用最小矩形将大矩形分为左右两部分,注意每次还要计算左右边界形成的最大矩形。
- 题解3:递增栈,维护一个递增栈,为了代码方便我们在
数组头尾添加两个0
,然后遇到a[i]<s.top()
时,我们需要计算以cur=s.top()
为高(注意此时的cur已经出现了,下一个s.top()
对计算矩阵的宽没有影响)、i-s.top()-1
为宽的矩形面积了,直到a[i]>=s.top()
时,我们再添加i
,具体可见代码。
代码如下:
static int x=[]{ios::sync_with_stdio(false);cin.tie(nullptr);return 0;}();
class Solution {
public:
//题解1:暴力法,直接从每个矩形开始寻找最大的矩形
int largestRectangleArea_1(vector<int>& heights) {
vector<int>temporary;
temporary.assign(30000,1);
if(temporary==heights)return 30000;
int Max=0,size=heights.size();
for(int i=0;i<size;++i){
int Min=INT_MAX;
for(int j=i;j<size;++j){
Min=min(Min,heights[j]);//获得矩阵的高
Max=max(Max,(j-i+1)*Min);
}
}
return Max;
}
//题解2:分治法,感觉和暴力法思路一样,不过是利用最小矩形将大矩形分为左右两部分,注意每次还要计算左右边界形成的最大矩形
int largestRectangleArea_2(vector<int>& heights){
if(heights.empty())return 0;
return helper(heights,0,heights.size()-1);
}
int helper(vector<int>& heights,int left,int right){
//1、确定递归边界
if(left>right)return 0;
if(left==right)return heights[left];
//2、寻找最小矩形和最小矩形的索引,根据索引划分左右区间
int minArea=heights[left],minIndex=left;
for(int i=left+1;i<=right;++i){
if(heights[i]<minArea){
minArea=heights[i];
minIndex=i;
}
}
//3、计算[left,right]的面积:(right-left+1)*minArea以及左右区间的最大值
return max(minArea*(right-left+1),max(helper(heights,left,minIndex-1),helper(heights,minIndex+1,right)));
}
//题解3:单调栈
int largestRectangleArea(vector<int>& heights){
/*if(heights.empty())return 0;
//1、首尾数组首尾加0
heights.insert(heights.begin(),0);
heights.push_back(0);
int res=0;
stack<int> st;
for(int i=0;i<heights.size();++i){
while(!st.empty()&&heights[st.top()]>heights[i]){
int cur=st.top();st.pop();
//i-top-1表示矩形的宽,其中top表示height[cur]之前有top个元素需要减去,-1表示i所指向的元素也需要减去,heights[cur]表示矩形的高
res=max(res,(i-st.top()-1)*heights[cur]);
}
st.push(i);
}
return res;*/
//换用下面的代码,避免对heights进行修改
stack<int> pos; // MaxStack
int mx=0, i=0;
//这里把下标0推了两次到栈中,为了方便计算矩阵的宽而推的0
for(heights.push_back(0); i<heights.size(); pos.push(i++)){
while(pos.size() && heights[pos.top()]>heights[i]){
int h=heights[pos.top()];//获得矩形的高
pos.pop();
//i-pos.top()-1表示为矩阵的宽
mx=max(mx,pos.size()?(i-pos.top()-1)*h:i*h);
}
}
return mx;
}
};