LeetCode76 最小覆盖子串

最小覆盖子串>>>
在这里插入图片描述

滑动窗口:定义一个hashMap存放字符串T中的所有元素,窗口框定S字符串,left---right确定当前所确定的元素,若在left-----right范围内不包含T则将right不断向右移动,若符合,则再将left向右移动直到不包含该T,用T中的map的每个值是否为0即可判断是否包含T


    /**
     *  重点分析
     * @param
     *         ,并且不要求顺序,之前已经用过很多次了,利用 HashMap,
     * 对于两个字符串 S = "ADOBECODEBANC", T = "ABCB",
     * 用 map 统计 T 的每个字母的出现次数,然后遍历 S,遇到相应的字母,就将相应字母的次数减 1,
     * 如果此时 map 中所有字母的次数都小于等于 0,那么此时的窗口一定包含了所有字母。
     */
    public String minWindow2(String s, String t) {
        Map<Character, Integer> map = new HashMap<>();
        //遍历字符串 t,初始化每个字母的次数
        for (int i = 0; i < t.length(); i++) {
            char char_i = t.charAt(i);
            map.put(char_i, map.getOrDefault(char_i, 0) + 1);
        }
        int left = 0; //左指针
        int right = 0; //右指针
        int ans_left = 0; //保存最小窗口的左边界
        int ans_right = -1; //保存最小窗口的右边界
        int ans_len = Integer.MAX_VALUE; //当前最小窗口的长度



        //遍历字符串 s
        while (right < s.length()) {
            char char_right = s.charAt(right);
            //判断 map 中是否含有当前字母
            if (map.containsKey(char_right)) {

                //当前的字母次数减一
                map.put(char_right, map.get(char_right) - 1);

                //开始移动左指针,减小窗口(满足map中的值一直为空的话)
                while (match(map)) { //如果当前窗口包含所有字母,就进入循环
                    //当前窗口大小
                    int temp_len = right - left + 1;
                    //如果当前窗口更小,则更新相应变量
                    if (temp_len < ans_len) {
                        ans_left = left;
                        ans_right = right;
                        ans_len = temp_len;
                    }
                    //得到左指针的字母
                    char key = s.charAt(left);
                    //判断 map 中是否有当前字母
                    if (map.containsKey(key)) {
                        //因为要把当前字母移除,所有相应次数要加 1
                        map.put(key, map.get(key) + 1);
                    }
                    left++; //左指针右移
                }
            }


            //右指针右移扩大窗口
            right++;
        }
        return s.substring(ans_left, ans_right+1);
    }

    //判断所有的 value 是否为 0
    private boolean match(Map<Character, Integer> map) {
        for (Integer 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、付费专栏及课程。

余额充值