9、最小覆盖子串

// 最小覆盖子串
    public String minWindow(String s, String t) {

        // 把t中的字符全部放到map中去
        Map<Character, Integer> map = new HashMap<>();
        for(char ch: s.toCharArray()) {
            map.put(ch, map.getOrDefault(ch, 0) + 1);
        }


        int left = 0;   // 窗口左边界
        int right = 0;  // 窗口右边界

        int strStart = 0;   // 满足条件的窗口的开始位置
        int windowLength = Integer.MAX_VALUE;   // 满足条件的窗口的长度

        while (right < s.length()) {
            // 记录右指针扫过的字符
            char rightChar = s.charAt(right);
            // 如果右指针扫过的字符在map中就减1
            if (map.containsKey(rightChar))
                map.put(rightChar, map.getOrDefault(rightChar, 0) - 1);
            // 记录之后指针右移
            right++;


            // 检查窗口是否把t中字符全覆盖了,若全覆盖了,要移动窗口的左边界
            // 找到最小的全部覆盖的窗口
            while (check(map)) {
                // 如果现在窗口比之前保存的窗口还要小,就要更新窗口
                if (right - left < windowLength) {
                    windowLength = right - left;
                    strStart = left;
                }

                // 移动窗口最左边的元素,也就是缩小窗口
                char leftChar = s.charAt(left);
                if (map.containsKey(leftChar))
                    map.put(leftChar, map.getOrDefault(leftChar, 0) + 1);
                // 左指针右移
                left++;
            }
        }

        // 如果找到合适的窗口就截取,否则就返回空
        if (windowLength != Integer.MAX_VALUE) {
            return s.substring(strStart, strStart + windowLength);
        }

        return "";
    }

    // 检查窗口是否把t中字符全覆盖了,如果map中所有的value都不大于0,则表示全覆盖了
    public static boolean check(Map<Character, Integer> map) {

        for (int value: map.values()) {
            if (value > 0) {
                return false;
            }
        }

        return true;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值