leetcode76. 最小覆盖子串-滑动窗口hard

leetcode76. 最小覆盖子串


给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

滑动窗口

看了题解才明白的。
首先用map记录t字符串每个字符出现的次数,然后窗口也有一个对应的map。每次窗口变化的时候,判断窗口的map里面的每个值是不是小于对应的tmap里面的每个值。如果是的话,说明这个还能更小,更新长度。

class Solution {
    HashMap<Character,Integer> tMap = new HashMap<>();
    HashMap<Character,Integer> sMap = new HashMap<>();
    public String minWindow(String s, String t) {
        for (int i = 0; i < t.length(); i++) {
            //初始化tMap
            tMap.put(t.charAt(i),tMap.getOrDefault(t.charAt(i),0) + 1);
        }
        int l = 0,r = 0, minLen = Integer.MAX_VALUE;
        int ansR = -1,ansL = -1;
        while (r < s.length()) {
            //左窗口不动,右窗口动
            if (r < s.length() && tMap.containsKey(s.charAt(r))) {
                //窗口右移,看看有没有字母加进来
                sMap.put(s.charAt(r),sMap.getOrDefault(s.charAt(r),0) + 1);
            }
            while (check() && l <= r) {
                //此时右窗口不动,左窗口开始动
                if (r - l + 1 < minLen) {
                    //新长度裁定
                    minLen = r - l + 1;
                    ansL = l;
                    ansR = l + minLen;
                }
                if (tMap.containsKey(s.charAt(l))) {
                    //窗口左移,要减掉出去的字母
                    sMap.put(s.charAt(l),sMap.getOrDefault(s.charAt(l),0) - 1);
                }
                l++;
            }
            r++;
        }
        return ansL == -1 ? "" : s.substring(ansL,ansR);
    }
    public boolean check() {
        Set<Map.Entry<Character,Integer>> tSet = tMap.entrySet();
        Iterator<Map.Entry<Character,Integer>> iterator = tSet.iterator();
        while (iterator.hasNext()) {
            Map.Entry<Character,Integer> entry = iterator.next();
            char k = entry.getKey();
            int v = entry.getValue();
            if (sMap.getOrDefault(k,0) < v) {
                return false;
            }
        }
        return true;
    }
}

leetcode 103

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值