C - Meximum Array
Meximum Array
思路:双指针算法
1.首先求出原数组的mex值
2.枚举原数组,将0~mex-1之间的数删除
(删除时可以添加一个st数组表示该数字是否被删除)
3.如果原数组中的某个数被删完,要更新mex的值
//双指针算法
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=2e5+5;
int a[N],b[N],st[N],num[N];
//a是原数组,b是求的数组,num存的是每个数出现的次数
int n,t;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
memset(b,0,sizeof b);
for(int i=1;i<=n;i++) cin>>a[i],num[a[i]]++;
int mex=0;
while(num[mex]>0) mex++;//找到整个数组的最大mex
int m=0;
for(int i=1;i<=n;i++)
{
int now=mex,cnt=0;
b[m++]=mex;
for(int j=i;j<=n;j++)
{
num[a[j]]--;//删去0~mex-1的数字,可以重复删
if(num[a[j]]==0&&a[j]<mex) mex=a[j];//该数字删完了,最大值只能是该数字,更新mex
if(!st[a[j]]&&a[j]<now) st[a[j]]=1,cnt++;//标记有没有被删过,cnt是跳出循环的条件
if(cnt==now)
{
i=j;
for(int i=0;i<now;i++) st[i]=0;
//TLE memset(st,0,sizeof st);//每次删除都要用,所以要初始化
break;
}
}
}
cout<<m<<endl;
for(int i=0;i<m;i++)
cout<<b[i]<<" ";
cout<<endl;
}
return 0;
}