package leecode;
import java.util.HashMap;
import java.util.Map;
/**
 * 567. 字符串的排列
 *
 * 给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
 *
 * 换句话说,s1 的排列之一是 s2 的 子串 。
 *
 *  
 * @author Tang
 * @date 2021/12/3
 */
public class CheckInclusion {
    /**
     * 判断s2中是否包含s1的所有字符子串,并且要连续
     * 与76题相似
     * 采用滑动窗口
     *
     * @param s1
     * @param s2
     * @return
     */
    public boolean checkInclusion(String s1, String s2) {
        char[] all = s2.toCharArray();
        char[] s = s1.toCharArray();
        //初始化need列表
        Map<Character, Integer> needMap = new HashMap<>();
        for (char c : s) {
            needMap.put(c, needMap.getOrDefault(c, 0) +1);
        }
        //初始化window列表
        Map<Character, Integer> window = new HashMap<>();
        //表示当前有几个元素满足  0 <= valid <= s.length
        //当valid == s.length时
        int valid = 0;
        int left = 0;
        int right = 0;
        //执行窗口右移
        while(right < all.length) {
            char c = all[right];
            right++;
            //此时说明元素c正需要
            //window中可以暂时存储过量的元素,反正最后也可以通过缩窗口调掉
            if(needMap.containsKey(c)) {
                window.put(c, window.getOrDefault(c, 0) +1);
                if(window.get(c).equals(needMap.get(c))) {
                    valid++;
                }
            }
            //如果这个c我不需要,那么进行缩左窗口试试能不能让这个c变成需要
            //如果不能就会把left缩到right对其,再从此刻重来
            while(left < right && right - left >= s.length) {
                //尝试更新结果
                if(valid == needMap.size()) {
                    return true;
                }
                char d = all[left];
                left++;
                if(needMap.containsKey(d)) {
                    if(window.get(d).equals(needMap.get(d))) {
                        valid--;
                    }
                    //把元素d干掉
                    window.put(d, window.get(d) - 1);
                }
            }
        }
        return false;
    }
    public static void main(String[] args) {
        String s1 = "abcdxabcde";
        String s2 = "abcdeabcdx";
        new CheckInclusion().checkInclusion(s1,s2);
    }
}