题意
本题输入一个序列,包含N个正整数,如果一个数左边的所有数都比它小、右边的所有数都比它大,那么称这个数为序列的一个“主元”。求序列中主元的个数。
思路
直接暴力判断会超时。
考虑大小的继承关系,假设序列为A,令数组leftMax记录序列A的每一位左边的最大数(含本位,下同),即leftMax[i]表示A[0] ~ A[i]的最大值,显然可以令leftMax[0] = 0。
从左到右遍历序列A,由于leftMax[i- 1]记录了A[0] ~ A[i-1]的最大值,因此如果A[i]比leftMax[i-1]大,说明leftMax[i]等于A[i];如果A[i]比leftMax[i-1]小,说明leftMax[i]等于leftMax[i-1]。
同样,令数组rightMin记录序列A的每一位右边的最小数(含本位),即rightMin[i]表示A[i+1] ~ A[n-1]的最小值,显然可以令rightMin[n] = INF (即一个很大的数)。从右到左遍历序列A,由于rightMin[i+1]记录了A[i+1] ~ A[n-1]的最小值,因此如果A[i]比rightMin[i+1]小,说明rightMin[i]等于A[i];如果A[i]比rightMin[i+1]大,说明rightMin[i]等于rightMin[i+1]。
接着就可以判断哪些是主元了。遍历序列A,如果leftMax[i-1]比A[i]小,且rightMin[i+1]比A[i]大,那么就说明A[i]是主元。全部判断完毕后进行输出即可。
const int N=1e5+10;
int a[N];
int lmax[N],rmin[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
lmax[i]=max(lmax[i-1],a[i]);
rmin[n+1]=INF;
for(int i=n;i;i--)
rmin[i]=min(rmin[i+1],a[i]);
vector<int> res;
for(int i=1;i<=n;i++)
{
if(a[i] > lmax[i-1] && a[i] < rmin[i+1])
res.pb(a[i]);
}
cout<<res.size()<<endl;
for(int i=0;i<res.size();i++)
if(i) cout<<' '<<res[i];
else cout<<res[i];
cout<<endl;
//system("pause");
return 0;
}