【滑动窗口法】——76. 最小覆盖子串

76. 最小覆盖子串

题目描述

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
示例 2:

输入:s = “a”, t = “a”
输出:“a”

解题思路

先右指针right遍历字符串s,在s中找到有t中所有字母的子串(也就是滑动窗口)
然后开始缩小滑窗,左指针left右移,去掉可以去掉的字母,记录这个子串(滑窗)的最小长度
右指针right继续遍历,不断更新滑窗最小长度

class Solution_76 {
    public String minWindow(String s, String t) {
        int n = s.length(), m = t.length();
        if(n < m) return "";

        Map<Character, Integer> need = new HashMap<Character, Integer>();
        for(int i = 0; i < m; i++){
            char c = t.charAt(i);
            need.put(c, need.getOrDefault(c, 0) + 1);
        }

        int[] res = new int[]{0, n};
        int left = 0, needCnt = m;
        for(int right = 0; right < n; right++){
            char cR = s.charAt(right);
            if(need.getOrDefault(cR, 0) > 0){
                needCnt--;
            }
            need.put(cR, need.getOrDefault(cR, 0) - 1);
            if(needCnt == 0){
                while(true){
                    char cL = s.charAt(left);
                    if(need.get(cL) == 0){
                        break;
                    }
                    need.put(cL, need.get(cL) + 1);
                    left++;
                }
                if(right - left < res[1] - res[0]){
                    res[0] = left;
                    res[1] = right;
                }
            }
        }
        return res[0] != 0 || res[1] != n ? s.substring(res[0], res[1] + 1) : "";
    }
}

posted @ 2021-03-10 21:17  your_棒棒糖  阅读(34)  评论(0编辑  收藏  举报