普通双指针法(超时,需要优化)
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
vector<int> lmin(n,0); //找左边第一个更小的坐标
vector<int> rmin(n,0); //找右边第一个更小的坐标
lmin[0]=-1;
for(int i=1;i<n;i++){
int t=i-1;
while(t>=0 && heights[t]>=heights[i]) t--; //优化:t--改为 t = lmin[t];
lmin[i] = t;
}
rmin[n-1] =n;
for(int i=n-2;i>=0;i-- ){
int t = i+1;
while(t<n && heights[t]>=heights[i]) t++; //优化:t++改为 t =rmin[t];
rmin[i] = t;
}
int res = 0;
for(int i=0;i<n;i++){
res = max(res,heights[i]*(rmin[i]-lmin[i]-1));
}
return res;
}
};
单调栈(自己实现了一下栈)
class Mystack{
private:
int tt=0; //数的下标
int stk[100010]={0};
public:
void push(int x){
stk[++tt] = x;
}
void pop(){
tt--;
}
int size(){
return tt;
}
int top(){
return stk[tt];
}
int empty(){
return tt==0;
}
};
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
Mystack st; //存储下标
heights.insert(heights.begin(), 0); // 数组头部加入元素0,防止单调递减数列,找不到左边第一个小的下标。
heights.push_back(0); // 数组尾部加入元素0,防止单调递增数列,找不到右边第一个小的下标。
int res=0;
for(int i=0;i<heights.size();i++){
while(!st.empty()&& heights[i] < heights[st.top()] ){
int h = heights[st.top()];
st.pop();
res = max(res, h * (i-st.top()-1));
}
st.push(i);
}
return res;
}
};