这是力扣第 438 题「找到字符串中所有字母异位词」,难度中等:

image.png

呵呵,这个所谓的字母异位词,不就是排列吗,搞个高端的说法就能糊弄人了吗?相当于,输入一个串 S,一个串 T,找到 S 中所有 T 的排列,返回它们的起始索引

直接默写一下 1. 最小覆盖子串 框架,明确刚才讲的 4 个问题,即可秒杀这道题:

// 注意:java 代码由 chatGPT🤖 根据我的 cpp 代码翻译,旨在帮助不同背景的读者理解算法逻辑。
// 本代码不保证正确性,仅供参考。如有疑惑,可以参照我写的 cpp 代码对比查看。
 
public List<Integer> findAnagrams(String s, String t) {
    Map<Character, Integer> need = new HashMap<>();
    Map<Character, Integer> window = new HashMap<>();
    for (int i = 0; i < t.length(); i++) {
        char c = t.charAt(i);
        need.put(c, need.getOrDefault(c, 0) + 1);
    }
 
    int left = 0, 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);
            if (window.get(c).equals(need.get(c))) {
                valid++;
            }
        }
        // 判断左侧窗口是否要收缩
        while (right - left >= t.length()) {
            // 当窗口符合条件时,把起始索引加入 res
            if (valid == need.size()) {
                res.add(left);
            }
            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);
            }
        }
    }
    return res;
}