力扣76.最小覆盖子串

76. 最小覆盖子串 - 力扣(LeetCode)

java 复制代码
class Solution {
    Map<Character, Integer> ori = new HashMap<Character, Integer>();
    // cnt:当前滑动窗口 [l, r] 里面,收集到的字符数量
    Map<Character, Integer> cnt = new HashMap<Character, Integer>();

    public String minWindow(String s, String t) {
        int tLen = t.length();

        for (int i = 0; i < tLen; i++) {
            char c = t.charAt(i);
            // 存在就+1,不存在默认0再+1
            ori.put(c, ori.getOrDefault(c, 0) + 1);
        }

        // 滑动窗口:初始r=-1,表示窗口里还没有元素
        int l = 0, r = -1;
        // len:记录满足条件的最小窗口长度;ansL、ansR 记录最终答案的左右下标
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        int sLen = s.length();

        // 外层循环
        while (r < sLen) {
            ++r; 

            //收缩左侧边界
            if (r < sLen && ori.containsKey(s.charAt(r))) {
                cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
            }

            while (check() && l <= r) {
                // 当前窗口长度比之前记录的更小 → 更新答案
                if (r - l + 1 < len) {
                    len = r - l + 1;
                    ansL = l;
                    ansR = l + len; // substring是左闭右开,所以ansR = l+len
                }
                //缩减左边界        :如果是t需要的字符,cnt计数-1
                if (ori.containsKey(s.charAt(l))) {
                    cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
                }
                ++l;
            }
        }

        // ansL=-1 说明从头到尾没有找到合法窗口,返回空串;否则截取子串
        return ansL == -1 ? "" : s.substring(ansL, ansR);
    }




    public boolean check() {
        //获取 ori 的迭代器,用来遍历 t 里【所有要求的字符】
        Iterator iter = ori.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();

            Character key = (Character) entry.getKey();
            Integer val = (Integer) entry.getValue();

            // 窗口里该字符数量不够,直接返回false,不满足条件
            if (cnt.getOrDefault(key, 0) < val) {
                return false;
            }
        }
        return true;
    }
}

缩减左边界时:移除后不应该即时就要检查移除后是否还符合要求吗

这个疑问抓得非常准!先说结论:

✅ 确实是移除之后立刻就会检查,但是不是写在减 cnt 这一行的后面,而是靠 while 循环的条件,下一轮循环开头去 check

java 复制代码
return ansL == -1 ? "" : s.substring(ansL, ansR);

等价于:

注意:

相关推荐
鸿蒙开发爱好者36 分钟前
下班后做的小工具和小游戏,我把它们整理成了 WyanHub
网络·人工智能·职场和发展·个人开发
地平线开发者1 小时前
征程6|用 hrt\_model\_exec 看清 YOLOv5x 的输入、原始输出和后处理
人工智能·算法
csdn_aspnet2 小时前
C++ 3个有序点的方向(Orientation of 3 ordered points)
c++·算法
赤生云电竞2 小时前
GPU算力共享平台架构实践:任务分发与资源隔离的关键配置
算法·架构·gpu算力
青少儿编程课堂3 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛
Oneshot5 小时前
DLX(Dancing Links)算法详解:求解数独最快的算法
算法
文丑颜不良啊6 小时前
LeetCode2541~2560题目解析
java·leetcode
青少儿编程课堂6 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园连连看解析
c++·python·算法·bfs·信息学竞赛
kongdong6 小时前
Hikyuu | RSI均值回归交易策略实现
算法·均值算法·回归·量化交易·交易策略·hikyuu