思路:尺取法
本篇题解适合小白参考,尤其是没有接触过尺取法的小白。
尺取法顾名思义就像一把尺子一样一点一点截取一个区间。
就照这个题来说。
我们需要让一个区间内26个字母都出现过并且长度最短。
我们就可以设置l和r作为指针使用指向下标0的地方。
然后将r一点一点向右挪动,我们需要挪动到什么时候呢,当然是满足题意的时候。
当我们挪动到一个位置使得[l,r]中包含了26个字母。我们停止挪动。
这时候我们需要干什么呢,我们就需要挪动左边的l指针,一点一点的往右挪动,直到不符合我们的条件之后,记录这一个区间的长度。
反反复复直到尾部即可。

import java.math.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.*;
public class Main {
    public static void main(String args[])throws IOException
    {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();
        String s = in.sval;
        int num[] = new int[26];
        int min=99999999;
        if(s.length()<=26)
            out.println(26);
        else
        {
            int sum=0,l=0,r=0;
            while(l<s.length()-25&&r<s.length())
            {
                if(sum<26)
                {
                    if(num[s.charAt(r)-'a']==0)
                        sum++;
                    num[s.charAt(r)-'a']++;
                    if(sum<26)
                        r++;
                    else{
                        min = Math.min(min,r-l+1);
                    }
                }
                if(sum>=26)
                {
                    num[s.charAt(l)-'a']--;
                    if(num[s.charAt(l)-'a']==0)
                        sum--;
                    if(sum<26)
                    { 
                        min = Math.min(min,r-l+1);
                        r++;
                    }
                    l++;
                }
            }
            out.println(min);
        }
        out.flush();
    }
                  }