0
点赞
收藏
分享

微信扫一扫

2020牛客巅峰赛 数据分析(单调队列思维)

天行五煞 2022-02-08 阅读 48


​​最大矩形面积​​

可以枚举每一个条形柱的高,可以一直往左延伸知道第一个比自己大的数

可以一直往右延伸直到第一个比自己大的数

这个过程使用单调栈来实现

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2e5+10;
int a[maxn],n;
int q[maxn],head=1,tail;
int l[maxn],r[maxn];
int main()
{
cin >> n;
for(int i=1;i<=n;i++)
{
cin >> a[i];
while( tail>=head && a[q[tail]]>a[i] )
r[q[tail--]] = i;//a[q[tail]]的右边a[i]第一个比它大
l[i] = q[tail];
q[++tail] = i;
}
int ans = 0;
l[1] = 0; r[n] = n+1;
for(int i=1;i<=n;i++)
{
if( r[i]==0 ) r[i]=n+1;
// cout << l[i] << " " << r[i] << " " << a[i]*(r[i]-l[i]-1) << endl;
ans = max( ans,a[i]*(r[i]-l[i]-1) );
}
cout << ans;
}

​​数据分析​​

这题也是异曲同工之妙

考虑 a i a_i ai这个数字能在哪些区间作为最大值

同样也是往左往右找第一个大于自己的数

那么 [ l , r ] [l,r] [l,r]内只要包含 a i a_i ai,就一定是作为最大值的

那么 a n s [ r − l + 1 ] = m i n ( a n s [ r − l + 1 ] , a i ) ans[r-l+1]=min(ans[r-l+1],a_i) ans[r−l+1]=min(ans[r−l+1],ai)

但是长度为 l e n len len可以作为最大值,说明长度为 [ 1 , l e n − 1 ] [1,len-1] [1,len−1]也可以作为最大值

所以还需要扫一遍

a n s [ i ] = m i n ( a n s [ i + 1 ] , a n s [ i ] ) ans[i]=min(ans[i+1],ans[i]) ans[i]=min(ans[i+1],ans[i])

class Solution {
public:
int q[100009],l[100009],r[100009],a[100009];
vector<int> getMinimums(vector<int>& numbers)
{
// write code here
int n = numbers.size();
for(int i=1;i<=n;i++) a[i] = numbers[i-1];
int head = 1,tail = 0;
for(int i=1;i<=n;i++)
{
while( tail>=head && a[i]>a[q[tail]]) r[q[tail--]]=i;
l[i] = q[tail];
q[++tail] = i;
}
vector<int>ans;
for(int i=0;i<n;i++) ans.push_back(1e9);
for(int i=1;i<=n;i++)
{
if( r[i]==0 ) r[i] = n+1;
int len = r[i]-l[i]-1;
ans[len-1] = min( ans[len-1],a[i] );
}
for(int i=n-2;i>=0;i--) ans[i] = min( ans[i],ans[i+1] );
return ans;
}
};



举报

相关推荐

0 条评论