字符串 (尺取法)
字符串
https://ac.nowcoder.com/acm/problem/18386
尺取法??好奇怪的名字.大概也就是让两个指针相互追逐,核心就是两个指针都是单调的,光往前不后退.从这一点看出复杂度就是的.
这里简单的说明一下这一道题符合为什么符合这个要求,其实这道题的本质也就是对于每一个(区间右端点)找一个符合条件最大的
(区间左端点)
然后对所有的计算一下区间长度,取最小值.
考虑我们已经知道了的符合要求的最大
,考虑
的符合要求最大
,由于
已经符合要求了,所以
必定符合要求.(因为我们的
是递增,也就是枚举每一位当做
)
这个时候的最大符合条件的左端点一定
>=
,所以可以发现左端点是单调不降的.就可以愉快的这样写了.
#include<bits/stdc++.h>
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define RE register
#define P 999911659
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair<ll,int>
#define PII pair<int,int>
#define pb(x) push_back(x)
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(RE int x=y;x<=z;++x)
#define fep(x,y,z) for(RE int x=y;x>=z;--x)
#define go(x) for(RE int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=1e6+10;
int cnt[30];
char c[N];
char *fs,*ft,buf[1<<15];
//inline char getc() {retur1n (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
inline int read()
{
int x=0,ff=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*ff;
}
inline bool check()
{
rep(i,0,25) if(!cnt[i]) return false;
return true;
}
int main()
{
//freopen("1.in","r",stdin);
scanf("%s",c+1);
int n=strlen(c+1);
bool flag=false;
int l=1,ans=INF;
rep(r,1,n)
{
cnt[c[r]-'a']++;
if(!flag&&check()) flag=true;
while(flag&&cnt[c[l]-'a']>1) cnt[c[l]-'a']--,++l;
if(flag) ans=min(ans,r-l+1);
}
put(ans);
return (0^_^0);
}
