[滑动窗口]leetcode76:最小覆盖字串(hard)

题目:
在这里插入图片描述
题解:

labuladong的深入浅出滑动窗口讲法,大家可以看看那个详细解法,我这里提供两份代码,一份是详细解法的代码,一份是8ms,战胜 98.87 %的代码。

代码如下:

class Solution {
public:
    string minWindow_1(string s, string t) {
        //最小字串的开始位置和最小长度
        int start=0,minLength=INT_MAX;
        
        unordered_map<char,int> needs;
        unordered_map<char,int> window;
        
        //建立字符串t的字符表
        for(char c:t)needs[c]++;
        
        //初始化窗口区间和记录窗口中满足的字符个数
        int left=0,right=0,match=0;
        
        //开始滑动窗口
        while(right<s.size())
        {
            char c1=s[right];
            if(needs.count(c1)){//字符c1存在于t的字符表中
                window[c1]++;//加入window
                if(window[c1]==needs[c1])//字符c1的个数已经满足字符表中的个数了
                    match++;
            }
            right++;
            
            while(match==needs.size())
            {
                if(right-left<minLength){//窗口的大小小于最小长度,更新字符串
                    start=left;
                    minLength=right-left;
                }
                char c2=s[left];
                if(needs.count(c2)){//c2在needs中,主要用来去除window中多余的字符数的
                    window[c2]--;//字符c2的个数减1
                    if(window[c2]<needs[c2])//字符c2出现次数不再符合要求
                        match--;
                }
                left++;//不管c2在不在needs中,都需要将left右移,因为此时的window的字符个数必然多于needs的字符个数
            }
        }
        
        return minLength==INT_MAX?"":s.substr(start,minLength);
    }
    
    string minWindow_2(string s, string t){
        //t不是s的字串
        if(s.size()<t.size())return "";
        
        //建立t的字符表
        int count[256] = {0};
        for(char c:t)count[c]++;
        
        int left=0,right=0;//窗口的左右指针
        int len=0,minLen=s.size();//len表示当前窗口匹配t中的字符个数
        string result;
        
        int n=s.size();
        for(;right<n;++right){
            if(count[s[right]]>0)//右指针指向s中的字符存在于count中
                len++;
            count[s[right]]--;//该字符的个数减1,表示s与t匹配了一个字符或者没有匹配到字符,该字符的个数可能为负数
            
            while(len==t.size())//s中的字符串已经满足t的字符串了
            {
                if(right-left+1<=minLen){//窗口大小小于最小子串,更新最小子串
                    minLen=right-left+1;
                    result=s.substr(left,right-left+1);
                }
                count[s[left]]++;//移动窗口的左指针
                
                if(count[s[left]]>0)len--;//字符的个数不在符合条件,表示window移动多了,正常匹配的话,count的每个字符为0
                
                left++;
            }
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值