本文要求的是包含所有画家的画作的最短连续序列,因此仅需要维护一个pair,记录序列的开头和结尾即可(用hh和tt分别表示);
从头到尾进行枚举,如果开头的数字出现过多次,则将序列的起始部分右移,同时也要把该画家出现的次数-1;如果序列右边刚加进去的数字只出现了一次,则证明序列中出现了一位新画家,那么要把序列所包含的画家位数+1;
此外,遍历的时候,应保证维护的序列长度最小(满足花销最少的要求)
C++ 代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int a[N];
int q[2010];
int cnt[N];
int hh,tt;
int n,k,m;
typedef pair<int,int> PII;
PII ans;
int main(){
cin>>n>>m;
hh=1,tt=0;
k=0;
for(int i=1;i<=n;i++) cin>>a[i];
ans={1,1e6};
for(int i=1;i<=n;i++){
tt=i;
cnt[a[tt]]++;//先跟新刚加入序列的个数增加
if(cnt[a[tt]]==1) k++;//如果刚加入的元素是序列中的新元素,更新画家数
while(hh<=tt&&cnt[a[hh]]>1){
cnt[a[hh]]--;
hh++;
}//更新队首元素,保证如果发生重复,则把队首后移
if(hh<=tt&&k==m) if((tt-hh)<(ans.second-ans.first)) ans={hh,tt};//保证元素数量尽可能少
}
cout<<ans.first<<" "<<ans.second<<endl;
return 0;
}