class Solution {
    // 这一题和最小覆盖子串有点相似,但是这里需要找的子串不能包括其他元素,需要加一个长度限制的检查
    // 异位词就是不同的排列方式
    // 用哈希表存储字符串中每个字符出现的次数
    // 维护一个p.length()长度的滑动窗口
    // 如果滑动窗口内的元素出现频率等于p的频率,则为字母异位词
    // 时间复杂度O(m + (n - m + 1)*26)
    // 改进的时间复杂度O(m + n)
    public List<Integer> findAnagrams(String s, String p) {
        // List<Integer> res = new ArrayList();
        // int[] pCount = new int[26];
        // for (int i = 0; i < p.length(); i++) {
        //     pCount[p.charAt(i) - 'a']++;
        // }
        // int left = 0; int right = 0;
        // int[] sCount = new int[26] ;
        // while (right < s.length()) {
        //     if(right - left + 1 > p.length()) {
        //         sCount[s.charAt(left) - 'a']--;
        //         left++;
        //     }
        //     sCount[s.charAt(right) - 'a']++;
        //     if(right - left + 1 == p.length()) {
        //         boolean isEqual = true;
        //         for (int i = 0; i < 26; i++) {
        //             if(pCount[i] != sCount[i]) {
        //                 isEqual = false;
        //                 break;
        //             }
        //         }
        //         if (isEqual) {
        //             res.add(left);
        //         }
        //     }
        //     right++;
        // }
        // return res;
       List<Integer> res = new ArrayList<>();
       int sLen = s.length(), pLen = p.length();
       if (sLen < pLen) {
            return res;
       }
       HashMap<Character, Integer> hs = new HashMap<>();
       for (int i = 0; i < pLen; i++) {
            char c = p.charAt(i); 
            hs.put(c, hs.getOrDefault(c, 0) + 1);
       }
       int required = hs.size(), current = 0;
       HashMap<Character, Integer> window = new HashMap<>();
       int left = 0, right = 0;
       while (right < sLen) {
            char word = s.charAt(right);
            if (hs.containsKey(word)) {
                window.put(word, window.getOrDefault(word, 0) + 1);
                if (window.get(word).equals(hs.get(word))) {
                    current++;
                }
            }
            while (right - left + 1 >= pLen) {
                char tmp = s.charAt(left);
                if (current == required) {
                    res.add(left);
                }
                if (hs.containsKey(tmp)) {
                    if (window.get(tmp).equals(hs.get(tmp))) {
                        current--;
                    } 
                    window.put(tmp, window.get(tmp) - 1);
                }
                left++;
            }
            right++;
       }
        return res;       
    }
}