题意:
给你一个长度为N的串,求最短连续子串的长度。子串要包含原串所有字母。(本题只包含大小写字母)
思路:
这是一道尺取法的典型例题,通过开始点和结束点的移动取得子串,并判断是否符合题意。每个点只会被访问两次,时间复杂度为O(n)。
注:尺取的规则是
1.若子串不符合条件,则子串向右扩张,向右移动结束点。
2.若子串符合条件,则子串向左收缩,向右移动开始点。
代码:
#include <bits/stdc++.h>
using namespace std;
int cut[150];
bool a[150];
int n,st,en,ans,all,sum;
string str;
void st_shift(){
if(cut[str[st]]==1) sum-=str[st];
cut[str[st]]--;
st++;
return ;
}
void en_shift(){
en++;
if(cut[str[en]]==0) sum+=str[en];
cut[str[en]]++;
return ;
}
int main()
{
while(cin>>n>>str){
sum=st=en=all=0;ans=n;
memset(cut,0,sizeof(cut));
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
if(!a[str[i]]){
all+=str[i];
a[str[i]]=1;
}
sum=str[0];
cut[str[0]]++;
while(en<n){
if(sum==all){
ans=min(ans,en-st+1);
st_shift();
}else{
en_shift();
}
}
cout<<ans<<endl