76. 最小覆盖子串

在这里插入图片描述
hard做的人想吐,暴力超时,要用滑动窗口和map,最重要的操作是弹出左边那些不要的元素,这样更新的left再去和minLen比。然后left再++,因为left++了,所以肯定不满足了,让right也++,直到right走到最后一位

class Solution {
public:
    string minWindow(string s, string t) {
        if(t.length() == 0) return s.substr(0,1);
        if(t.length() > s.length()) return "";
        //window肯定是滑动窗口
        //int left = -1, minLen = INT_MAX;
        //不用数组记录每一位往后数几位才是最大值,直接记录最小长度的下标和长度即可
        //还得来一个map记录当前字符串中还没被消耗的个数
        /*for(int i = 0; i <= s.length()-t.length(); ++i){
            unordered_map<char,int> ma;
            for(int j = 0; j < t.length(); ++j){
                ma[t[j]]++;
            }
            //来一个index判断被消耗掉几个
            int index = t.length();
            for(int j = i; j < s.length(); ++j){
                if(ma[s[j]] != 0){
                    ma[s[j]]--;
                    index--;
                }
                if(index == 0 && minLen > j-i+1){
                    left = i;
                    minLen = j-i+1;
                }
            }
        }*/        
        //暴力超时用滑动窗口
        unordered_map<char,int> ma;
        for(char c:t){
            ma[c]++;
        }
        //index是t中没被消耗掉的字符个数
        int left = 0, right = 0,minLen = INT_MAX, index = t.length(), start = 0;
        while(right < s.length()){
            //当index==0时,证明一个窗口找好了,但是不一定是最小窗口,将left一直右移,将前面那些没用的字符全部不要,直到找到第一个需要的字符,也就是ma[s[left]]刚好为0的字符,此时这个窗口是最小的,更新minLen和start,并将left++
            //left++后,一定不满足了,所以r++重新找新的窗口。
            if(ma[s[right]] > 0){
                index--;
            }
            ma[s[right]]--;
            if(index == 0){
                while(left < right && ma[s[left]]<0){
                    //把前面没有那些字符都去除
                    ma[s[left++]]++;
                }
                if(right-left+1 < minLen){
                    start = left;
                    minLen = right-left+1;
                }
                ma[s[left]]++;
                index++;
                left++;
            }
            right++;
        }
        if(minLen == INT_MAX) return "";
        else return s.substr(start,minLen);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值