LeetCode_滑动窗口_困难_76.最小覆盖子串

x33g5p2x  于2022-01-13 转载在 其他  
字(1.6k)|赞(0)|评价(0)|浏览(341)

1.题目

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

注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

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

示例 2:
输入:s = “a”, t = “a”
输出:“a”

示例 3:
输入: s = “a”, t = “aa”
输出: “”
解释: t 中两个字符 ‘a’ 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成

进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring

2.思路

(1)滑动窗口
参考链接:我写了套框架,把滑动窗口算法变成了默写题

3.代码实现(Java)

//思路1————滑动窗口
public String minWindow(String s, String t) {
    int sLen = s.length();
    HashMap<Character, Integer> window = new HashMap<Character, Integer>();
    HashMap<Character, Integer> need = new HashMap<Character, Integer>();
    //将字符串t中的字符存入哈希表need中,key/value为字符/出现的次数
    for(int i=0;i<t.length();i++){
        char c = t.charAt(i);
        need.put(c, need.getOrDefault(c,0) + 1);
    }
    int left = 0,right = 0;
    //valid记录窗口中t中不重复字符的个数
    int valid = 0;
    //记录最小覆盖子串的起始索引以及长度
    int start = 0,minLen = Integer.MAX_VALUE;
    while(right < sLen){
        char c = s.charAt(right);
        right++;
        //更新窗口内的数据
        //如果字符c存在于t中,则将其加入到window中
        if(need.containsKey(c)){
            window.put(c, window.getOrDefault(c,0) + 1);
            //如果t中所有的字符c都已经加入到窗口中
            /* 使用"=="比较Integer类型的值时,值的范围只能在-128到127之间,否则会出错 详情请见https://www.cnblogs.com/mrhgw/p/10449391.html */
            if(window.get(c).equals(need.get(c))){
                valid++;
            }
        }

        //判断左侧窗口是否要收缩
        //t中的所有字符都已经加入到窗口中
        while(valid == need.size()){
            //更新最小覆盖子串
            if(right - left < minLen){
                start = left;
                minLen = right - left;
            }
            //d是即将移出窗口的字符
            char d = s.charAt(left);
            left++;
            //更新窗口内的数据
            if(need.containsKey(d)){
                if(window.get(d).equals(need.get(d))){
                    valid--;
                }
                window.put(d,window.get(d)-1);
            }
        }
    }
    return (minLen == Integer.MAX_VALUE) ? "":s.substring(start,start+minLen);
}

相关文章