力扣 76.最小覆盖子串

在这里插入图片描述
我太菜了,这题做不出来,超时代码:

class Solution {
public:
    string minWindow(string s, string t) {
        int n=s.size();
        int m=t.size();
        if(n<m) return "";

        bool first=true;//第一次标记
        string res="";
        map<char,int> mapt;//储存个字符及其个数
        for(int i=0;i<m;i++) mapt[t[i]]++;
        /*for(auto a=mapt.begin();a!=mapt.end();a++){
            cout<<a->first<<" "<<a->second<<endl;
        }
        cout<<endl;*/

        for(int i=0;i<=n-m;i++){
            if(mapt[s[i]]>0){//子串首字母在t中存在
                //cout<<s[i]<<" "<<i <<" ";
                string temp=jude(mapt,s,i,m);
                //cout<<temp<<endl;
                if(first && temp=="") return "";//不存在满足的子串
                else if(temp!="" &&(temp.size() < res.size() || first)){//如果新的子串比原来的短 或者 第一个子串
                    res=temp;
                    first=false;
                }
                int k=temp.size();
                //while(i+k<n && mapt[s[i+k]]==0) i++;//节约时间,子串后一个t中不存在,i++(无需循环调用jude函数)
               
            }
        }
        return res;
    }

    string jude(map<char,int> mapt,string s,int i,int m){
        int j=i;
        int count=m;//记录未涵盖m的字符个数  因为首字母已匹配 所以减1
        while(j<s.size() && count>0){
            if(mapt.count(s[j])) {
                mapt[s[j]]--;
                count--;
            }
            j++;
        }   
        if(count==0)  return s.substr(i,j-i);//返回满足子串  注意此时j的下标为子串后面的一个字符的下标
        else  return "";//不存在满足的子串
    }
};

参考评论区佬们的答案:

class Solution {
public:
    string minWindow(string s, string t) {
       int n=s.size(), m=t.size();
       if(n<m) return "";
       string res="";//最短子串
       map<char,int> ms, mt;
       for(int i=0;i<m;i++)  mt[t[i]]++;//初始化
       int l=0;//子串的左下标
       int count=0;//有效字符的个数
       for(int i=0;i<n;i++){
           ms[s[i]]++;
           if(ms[s[i]]<=mt[s[i]]) count++;//增加有效字符
           while(l<i && ms[s[l]]>mt[s[l]]){//从左边删除冗余部分
               ms[s[l]]--;
               l++;
           }
           if(count==m){//前面是边增有效字符边删除冗余部分
               if(res=="" || i-l+1<res.size())
                    res=s.substr(l,i-l+1);
           }
       }
       return res;
    }
};

在这里插入图片描述
如果要改进,可将map<char,int> ms, mt; 换成 int ms[‘z’-‘A’+1], mt[‘z’-‘A’+1]来节约内存。

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值