CodeForces 701C They Are Everywhere
双指针。
先统计一下字符种类数$sum$,然后进行尺取。
如果目前的区间$[L,R]$中不同字符个数$k<sum$,那么区间右端往右移动一位,更新种类数。
如果目前的区间$[L,R]$中不同字符个数$k==sum$,更新答案,然后区间左端往右移动一位,更新种类数。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0;while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } } const int maxn=100010; char s[maxn]; int n,sum,f[maxn],k,ans; int main() { scanf("%d%s",&n,s); for(int i=0;s[i];i++) { if(f[s[i]]) continue; sum++; f[s[i]]=1; } memset(f,0,sizeof f); int L=0,R=-1; k=0; ans=n; while(1) { if(k<sum) { if(R==n-1) break; R++; if(f[s[R]]==0) k++; f[s[R]]++; } else if(k==sum) { ans=min(R-L+1,ans); f[s[L]]--; if(f[s[L]]==0) k--; L++; } } printf("%d\n",ans); return 0; }