leecode76. 最小覆盖子串

76. 最小覆盖子串

给你一个字符串 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 的子串中,
因此没有符合条件的子字符串,返回空字符串。

思路:本题采用滑动窗口的模式来解决,首先如何判断s中是否包含t,我们通过记录t中字符出现的频数(即记录每种字符出现的次数),并且用distance来记录。当窗口中s出现t种含有字符的频数小于t的频数时distance++为什么是小于,那是因为distance是用来判断窗口中是否满足包含完整的t,窗口中只要满足就进行下一步找最小的,此时没有到找最下的这一步,一次允许存在窗口中允许大于t种某类或者某几类字符的存在,加入s= "ABABABBAACC"t = "ABC",那么s第一次满足涵盖t的就应该是"ABABABBAAC"之后我们在去对这个进行窗口缩小。窗口缩小的结束条件为distance != tLength,那distance什么时候变化,当窗口中含有的t的字符任意某个 = t的出现的次数 ,"ABABABBAAC"的最小就应该是BAAC

思路种有两个关键点:1.窗口首先一直向右扩大,那什么时候停止?2.窗口停止后我们需要找到最小覆盖,什么时候是最小覆盖

问题一:当窗口右侧一直右移扩大时第一个满足覆盖时停止

问题二:当窗口左侧一直右移缩小时(窗口大小为右侧-左侧),最后一个满足覆盖

代码如下:

class Solution {
    public String minWindow(String s, String t) {
        int sLength = s.length();
        int tLength = t.length();
        if(tLength>sLength||tLength==0||sLength==0){
            return "";
        }
        char[] charArrayS = s.toCharArray();
        char[] charArrayT = t.toCharArray();
        char[] tFreq = new char[128];
        char[] winFreq = new char[128];
        for(char c : charArrayT){
            tFreq[c]++;
        }
        int left = 0;
        int right = 0;
        int distance = 0;
        int mLen = sLength+1;
        int begin = 0;
        while(right < sLength){
            if(tFreq[charArrayS[right]] == 0){
                right++;
                continue;
            }
            if(winFreq[charArrayS[right]]<tFreq[charArrayS[right]]){
                distance++;
            }
            winFreq[charArrayS[right]]++;
            right++;
            while(distance == tLength){
                if(right-left<mLen){
                    mLen = right-left;
                    begin =left;
                }
                if(tFreq[charArrayS[left]] == 0){
                    left++;
                    continue;
                }
                if(winFreq[charArrayS[left]]==tFreq[charArrayS[left]]){
                    distance--;
                }
                winFreq[charArrayS[left]]--;
                left++;
            }
        }
        return mLen == sLength+1 ? "" : s.substring(begin,begin+mLen);
    }
}
posted @ 2022-07-20 17:19  zqy123  阅读(33)  评论(0编辑  收藏  举报