leetcode76.最小覆盖子串

参考:
https://leetcode.com/problems/minimum-window-substring/discuss/26840/Sharing-my-straightforward-O(n)-solution-with-explanation

代码其实看的不太懂

string minWindow(string S, string T) {
    string result;
    if(S.empty() || T.empty()){
        return result;
    }
    unordered_map<char, int> map; //存放T字符串,键是字母,值是出现的次数
    unordered_map<char, int> window; //用于维护一个window窗口并记录其中在T里的字母即次数,其左右边界分别是slow和fast
    for(int i = 0; i < T.length(); i++){ //记录T 
        map[T[i]]++;
    }
    int minLength = INT_MAX; //记录最小长度
    int letterCounter = 0;  //记录窗口内在T里出现的字母的总次数
    
    for(int slow = 0, fast = 0; fast < S.length(); fast++){ //slow是左边界,fast是右边界
        char c = S[fast]; //当前字母
        //先找到一个包含所有T内字母的窗口
        if(map.find(c) != map.end()){ //如果当前字母在T里出现
            window[c]++;  //放入window里
            if(window[c] <= map[c]){ //当前字母在window里的次数少于在T里的次数,说明当前字母不属于多余的(比如A在T里出现了3次,但是在window里有4次就是多余的)
                letterCounter++; //当letterCounter等于T.len()时说明已经找到一个窗口包含T内所有的字母
            }
        }
        if(letterCounter >= T.length()){ //说明可能有了多余的字母,开始优化
            while(map.find(S[slow]) == map.end() || window[S[slow]] > map[S[slow]]){ //第一个条件表示窗口里slow指的字母不是T里的字母,可以将左窗口向右滑;第二个条件表示window里slow值的字母是多余的,也可以向右滑
                window[S[slow]]--;
                slow++;  //窗口右滑
            }
            if(fast - slow + 1 < minLength){ //每次记录最小窗口
                minLength = fast - slow + 1;
                result = S.substr(slow, minLength);
            }
        }
    }
    return result;
}

思路:
https://blog.csdn.net/zhangxiao93/article/details/49892665
先找一个包含所有字母T的窗口,然后如果最左边的字母不是T里的字母或者是多余的字母就可以将右窗口向右滑动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值