方法:区间伸缩
时间复杂度:O(n)
用两个变量l和r来枚举区间
如果l到r的区间不满足要求,r++
如果l到r的区间满足要求,记录答案,l++
ACcode:(详细注释,安全食用~)
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10,M=2e3+10;
int a[N],b[M],n,m,L,R,k;
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
int l=1,r=1,ans=1<<30;
b[a[1]]=1,k=1;//当前区间中画家出现的次数,当前区间有多少个画家
//因为r,l=初始化为1,即认为a[1]画家已经在当前区间内,所以:b[a[i]]=1,k=1
while(l<=r&&r<=n){
if(k==m){//当前有区间有m个画家了,满足要求,
//那r(右指针就先不用动,开始移动左指针向右)
//看是不是l向右移动当前区间是不是还是m个画家
if(ans>r-l+1){//更新最小区间
ans=r-l+1;
L=l,R=r;//标记最小区间,方便输出
}
b[a[l]]--;
if(b[a[l]]==0) k--;//左指针向右移动导致该区间本来只有该画家的唯一幅画也没了
//那该画家这不在当前k画家中了,所以k--
//k--一旦减一下一就会进入else(又轮到右指针r寻找不够的那几个画家)
l++;//左指针向右移动
}
else{
r++;
b[a[r]]++;
if(b[a[r]]==1)k++;//等于1代表当前画家是第一次出现,
//所以K要+1,(明确k的含义)
}
}
cout<<L<<" "<<R<<"\n";
}
int main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
solve();
return 0;
}
over~