135 最短包含字符串的长度
Table of Contents

ac

给定字符串str1str2,求str1的字串中含有str2所有字符的最小字符串长度。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;


public class Main {
    public static Scanner sc = new Scanner(System.in);

    public static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    public static long mod = (long)Math.pow(2,29);

    public static void main(String[] args) throws Exception {
        String str1 = reader.readLine();
        String str2 = reader.readLine();
        int ans  = getSmallInclude(str1, str2);
        System.out.println(ans);
    }

    static int getSmallInclude(String str1, String str2){
        int n = str1.length();
        int m = str2.length();
        if(n < m){
            return 0;
        }
        char[] s1 = str1.toCharArray();
        char[] s2 = str2.toCharArray();

        Map<Character, Integer> map = new HashMap<>(256);
        for(int i=0;i<m;i++){
            if(map.containsKey(s2[i])){
                map.put(s2[i], 1 + map.get(s2[i]));
            }else {
                map.put(s2[i], 1);
            }
        }

        int left = 0;
        int right = 0;
        int match = m;
        int minLen = Integer.MAX_VALUE;

        while (right != n){
            // 但前字符的记录要先减1
            char c = s1[right];
            if(map.containsKey(c)){
                map.put(c, map.get(c) - 1);
            }else {
                map.put(c, -1);
            }
            // map.get(c) >= 0 说明 match 了一个
            if(map.get(c) >= 0){
                match --;
            }
            if(match == 0){ // 表示 s1[left...right] 完全包括了 s2
                // 左边开始,只要 map.get(s1[left]) < 0 就说明 即使少了 s1[left] 也是可以包括 s2 的
                while (map.containsKey(s1[left]) && map.get(s1[left]) < 0){
                    char c2 = s1[left];
                    if(map.containsKey(c2)){
                        map.put(c2, map.get(c2) + 1);
                    }else {
                        map.put(c2, 1);
                    }
                    left++;
                }
                minLen = Math.min(minLen, right - left + 1);
                // 开始新的一轮
                match ++;
                char c2 = s1[left];
                if(map.containsKey(c2)){
                    map.put(c2, map.get(c2) + 1);
                }else {
                    map.put(c2, 1);
                }
                left++;
            }
            right++;
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
    }

}
/*
adabbca
acb
3
*/