1.维护递增堆,注意是完全递增
(1)从左向右维护,可以找到该数左边第一个比该数小的位置/值
(2)从右向左维护,可以找到该数右边第一个比该数小的位置/值
e.g:
原题链接
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010;
typedef long long LL;
LL ans;
int h[N],leftt[N],rightt[N];
int n;
int q[N];
int tt;
void getl()
{
memset(q,0,sizeof(q));
tt=0;
q[++tt]=0;
h[0]=-1; //不能为0,h[i]可能为0,会把所有栈中元素弹出
for(int i=1;i<=n;i++)
{
while(tt>0 && h[q[tt]]>=h[i])
tt--;
leftt[i]=q[tt]; //leftt[i]记录左边第一个比他小的位置,如果h[0]==0,则1~n中h[i]==0,leftt[i]找不到
q[++tt]=i;
}
}
void getr()
{
tt=0;
memset(q,0,sizeof(q));
q[++tt]=n+1;
h[n+1]=-1;
for(int i=n;i>=1;i--)
{
while(tt>0 &&h[q[tt]]>=h[i])
tt--;
rightt[i]=q[tt];
q[++tt]=i;
}
}
int main()
{
while(cin>>n,n)
{
for(int i=1;i<=n;i++)
scanf("%d",&h[i]);
getl();
getr();
ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,LL(LL(h[i])*(rightt[i]-leftt[i]-1))); //!! 注意LL(LL(h[i])),不然爆int
}
cout<<ans<<endl;
}
return 0;
}
1.维护递减堆,注意是完全递减
(1)从左向右维护,可以找到该数左边第一个比该数大的位置/值
(2)从右向左维护,可以找到该数右边第一个比该数大的位置/值
class Solution {
public:
bool find132pattern(vector<int>& nums) {
int right=INT_MIN;//维护一个最大2
stack<int> stk;
for(int i=nums.size()-1;i>=0;i--)
{
if(nums[i]<right) return true; //把nums[i]看出1
while(stk.size() && stk.top()<nums[i]) //上面不成立,则把nums[i]看成3
{
right=max(right,stk.top()); //维护最大2,直到遇到第一个比该数大的数,即找比nums[i]小的最大数,该数一定在栈中!!
stk.pop();
}
stk.push(nums[i]);//维护单调栈,以便找到下一个nums[i]最右边第一个比该数大的数
}
return false;
}
};