76. 最小覆盖子串/C++

在这里插入图片描述
思路:
使用一个滑动窗口来表示s子串。
用一个hash表来表示s子串还需要哪些字母才能包含t的全部字母
另外再用一个count来计数,count等于t的长度,那么该子串就是一个符合条件的子串。
再将左指针向右移动。

string minWindow(string s, string t) {
		//如果s比t短,直接返回空字符串
        if(s.size()<t.size())
            return "";
        
        //hashmap存储还需要多少字符才能达到要求
        //注意:hashmap的值是可以为负数的,比如hashmap[c]=-1就表示该子串所包含的c比要求的还多一个
        //还有,hashmap中的元素项都是t字符串的字符,
        //如果不是t字符串中的字符,我们根本就不处理,右边界直接右移
        map<char,int> hashmap;
        for(auto c:t)
            hashmap[c]= hashmap.find(c)!=hashmap.end() ? hashmap[c]+1 : 1;
        
        //用来计数,所包含的符合要求的字符有多少
        int count=0;
        //目前子串的左右边界指针
        int left=0;
        int right=0;
        //最短长度,以及左右边界
        int minleft=0;
        int minright=0;
        int minlen=INT_MAX;
        
        //窗口向右扩展
        for(;right<s.size();++right){
        	//如果s[right]是t中的字符
            if(hashmap.find(s[right]) != hashmap.end()){
            	//如果我们还需要s[right],那么将其纳入窗口后,所包含的符合要求的字符就又多了一个
                if(hashmap[s[right]]>0)
                    ++count;
                //所需要的字符也减少了一个
                --hashmap[s[right]];
            }
            
            //此时我们得到了所需要的子串
            while(count == t.size()){
            	//如果该子串更短,则更新记录
                if(right-left<minlen){
                    minright=right;
                    minleft=left;
                    minlen=right-left;
                }
                
                //如果s[left]是t中的字符
                if(hashmap.find(s[left]) != hashmap.end()){
                	//如果s[left]是我们还需要的或者刚刚够的,那么所包含的符合要求的字符就减少一个
                	//如果此时hashmap[s[left]]<0,就说明子串所包含的字符还有多的,不需要减少
                    if(hashmap[s[left]]>=0)
                        --count;
                    //所需要的字符增加一个
                    ++hashmap[s[left]];
                }
                //左边界右移
                ++left;
            }
        }
        //最后如果存在符合条件的子串,则构建该子串
        return minlen == INT_MAX ? "" : string(s.begin()+minleft,s.begin()+minright+1);
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值