【leetcode 76. 最小覆盖子串】解题报告

思路:滑动窗口思想

方法一:滑动窗口

    string minWindow(string s, string t) {
        // 1.tdict记录T中每个字母与字母个数
        // 2.维护一个滑动窗口字母的计数表sdict,计数当前窗口内T中字母出现的次数
        // 3.当窗口内T中字母出现的次数大于等于T中每个字母出现的次数一样,这时第一个最短子串出现,再逐步从左边缩短窗口,直到不满足上述条件,然后再从右边扩大窗口,直到满足条件时,再进行最短子串长度对比,一直更新最短长度子串直到结束
        if (s.size()<t.size()||s.size()==0) return "";
        unordered_map<char,int> tdict,sdict;
        int l=0,r=0,k=t.size();
        for(auto it:t)  // 填充T的字母与字母计数表
        {
            if (!tdict.count(it)) tdict[it]=1;
            else tdict[it]++;
        }
        string res="";
        for(r=0;r<s.size();++r)
        {
            if (tdict.count(s[r])) // 有字符,则进行记录
            {
                if (!sdict.count(s[r]))
                    sdict[s[r]]=0;
                sdict[s[r]]++;
                if (sdict[s[r]]<=tdict[s[r]])
                    k--;
            }
            while(k==0) // 满足条件,滑动窗口从左边逐步缩短,直到剔除第一个属于T中的字符为止
            {
                if (res.empty()||r-l+1<res.size())  // 最短子串更新
                    res=s.substr(l,r-l+1);
                if(tdict.count(s[l]))
                {
                    sdict[s[l]]--;
                    if (sdict[s[l]]<tdict[s[l]])
                        k++;
                }
                l++;
            }
        }
        return res;
    }

 

posted @ 2019-05-03 11:00  byjz  阅读(119)  评论(0编辑  收藏  举报