尺取法。

1.从第一个字符开始,向右移动右界至子串合法,用vis数组记录每个字母出现的次数,cnt表示vis记录次数为零的字母数。

2.当cnt=0时,此时每个字母都至少出现了一次,也就是说此时的长度就是一个合法子串的长度。更新ans。同时向右移动左界至子串不合法,移动过程中不断更新ans。返回第一步直至右界超过字符串长度。

3.输出ans。

代码:

#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
#include <deque>
using namespace std;

typedef long long ll;
typedef pair<int,int> P;
typedef pair<P,int> Q;

const int inf1=2e9+9;
const ll inf2=8e18+9;
const ll mol=1e9+7;
const int maxn=1e5+9;
const ll maxx=1e12+9;

string s;
int vis[26],cnt=26;
int main()
{
    cin>>s;
    int len=s.size();
    int p1=0,p2=0,ans=inf1;
    while(p2<len||!cnt)
    {
        if(cnt)
        {
            if(!vis[s[p2]-'a']) cnt--;
            vis[s[p2]-'a']++;
            p2++;
        }
        if(!cnt)
        {
            ans=min(ans,p2-p1);
            if(vis[s[p1]-'a']==1) cnt++;
            vis[s[p1]-'a']--;
            p1++;
        }
    }
    cout<<ans<<endl;
}