【滑动窗口】438. 找到字符串中所有字母异位词

438. 找到字符串中所有字母异位词

滑动窗口解法

  • 创建两个Map 一个记录实际需要的有效字符 另一个记录窗口内的有效字符个数
  • 初始化need
  • 每次遍历一个字符 判断是不是有效字符 如果是 更新window 另外判断window中有效字符的个数是不是等于need中有效字符的个数 如果是更新valid
  • 当窗口长度过大 需要缩小边界 判断左边窗口的字符 如果是有效字符 更新window和valid
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        Map<Character,Integer> need = new HashMap<>();// 记录P中每一个字符
        Map<Character,Integer> window = new HashMap<>();// 记录窗口内部的所有有效字符

        // 初始化
        for(int i  = 0; i < p.length(); i++){
            char c = p.charAt(i);
            need.put(c,need.getOrDefault(c,0) + 1);
        }

        int left = 0;
        int right = 0;
        int valid = 0;// 记录窗口内有效字符是否已经达到要求
        List<Integer> res = new ArrayList<>();

        while(right < s.length()){
            char c = s.charAt(right);
            right++;

            // 进行窗口内数据的一系列更新
            // 计算当前有效字符的满足个数
            if(need.containsKey(c)){
                window.put(c,window.getOrDefault(c,0) + 1);// 记录有效字符

                // 判断窗口内的有效字符和 need中的有效字符个数是不是相等  因为很可能不相等
                // 如果是 直接valid++ 代表有一个字符的个数已经满足了
                if(window.get(c).equals(need.get(c))){
                    valid++;
                }
            }

            // 判断左边的窗口是不是要收缩
            while(right - left >= p.length()){
                if(valid == need.size()){
                    // 说明找到一个字母异位词  记录一下起始边界
                    res.add(left);
                }

                // 取出左边窗口边界的字符  进行更新操作  更新valid
                char d = s.charAt(left);
                // 窗口缩小
                left++;

                // 进行窗口内数据的一系列更新
                if(need.containsKey(d)){

                    // 将窗口内满足条件的有效字符减一 
                    if(window.get(d).equals(need.get(d))){
                        valid--;
                    }

                    window.put(d,window.get(d) - 1);// 重新写入window窗口
                }

            }
        }
        return res;
    }

    
}

你可能感兴趣的:(#,Leetcode,java,开发语言)