力扣 76.最小覆盖子串

发布时间:2024年01月24日

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

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]来节约内存。

文章来源:https://blog.csdn.net/weixin_61321344/article/details/135793799
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。