题目链接
题目:

分析:
- 要找的是在s中和p是异位词的子串, 也就是说子串大小和p相同, 那么就是窗口大小固定的滑动窗口问题
 - 可以使用哈希数组来记录每个元素出现的个数, 定义hash1存放p中的各元素个数
 - 定义left = 0; right = 0;
 - 进窗口 让right指向的元素进窗口, 即更新hash2中的元素即个数
 - 判断 判断窗口大小是否小于等于p的长度
 - 出窗口 如果窗口大小大于p的长度, 则出窗口, 此时不需要循环出窗口, 因为窗口大小是固定的, left只需向前移动一步即可
 - 更新结果 如果此时hash2和hash1相等 说明此子串和p是异位词, 返回此时left
 
思考:
想要判断hash1和hash2相等, 需要分别遍历两个数组, 虽然这道题中元素都是小写字母, 时间复杂度不高, 但如果元素变复杂, 则很难比较相同, 如果我们可以用另一种方式:
- 定义一个count = 0, 来记录窗口中"有效数据"的个数, 有效数据是指此数据是p中的元素且此元素在窗口中的个数小于等于p中的个数
 - 当进窗口时, 如果此时right指向的元素在hash2中的个数小于在hash1中的个数, 说明此时是有效数据, 则count++
 - 当出窗口时,如果此时left指向的元素在hash2中的个数小于在hash1中的个数,说明此时是有效数据, 则count--
 - 更新结果时,只需要判断此时count的大小和p的大小是否相等, 如果相等, 则返回left
 
代码:
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> list = new ArrayList<>();
        char[] ss = s.toCharArray();//为了方便转化成字符数组
        char[] pp = p.toCharArray();
        int[] hash1 = new int[26];
        for(char x:pp){
            hash1[x - 'a']++;
        }
        int[] hash2 = new int[26];
        int left = 0;
        int right = 0;
        int count = 0;
        while(right<ss.length){
            char in = ss[right];
            hash2[in-'a']++;
            if(hash2[in-'a'] <= hash1[in-'a']) count++;
            if(right-left+1>pp.length){
                char out = ss[left];
                if(hash2[out-'a'] <= hash1[out-'a']) count--;
                hash2[out-'a']--;
                left++;
            }
             if(count == pp.length){
                    list.add(left);
                }
            right++;
        }
        return list;
    }
} 
                


















