思路:
本题要选择一个区间并要判断弹珠的数量是否符合要求(颜色1的弹珠有k1个,颜色2的弹珠有k2个,...,颜色m的弹珠有km个)。因此要用尺取法来做。
先移动右指针,直到满足条件停止,这时移动左指针。找到最小区间长度的值。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int a[N],k[N],cnt[N],sum=0;
bool flag[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
cin>>k[i];
sum+=k[i];//共要几个颜色。
}
int l=1,r=1,num=0,mins=200005;
while(l<=n&&r<=n){
while(r<=n&&num<m){//移动右指针
cnt[a[r]]++;//新增颜色数量加一
if(!flag[a[r]]&&cnt[a[r]]>=k[a[r]]){//判断是否是才满族的。
num++;
flag[a[r]]=true;
}
r++;
}
while(l<=r&&num==m){//移动左指针
mins=min(mins,r-l);
cnt[a[l]]--;//减少的颜色减一
if(flag[a[l]]&&cnt[a[l]]<k[a[l]]){
num--;
flag[a[l]]=false;
}
l++;
}
}
if(mins!=200005) cout<<mins-sum;//mins没有改变
else cout<<-1;
return 0;
}