leetcode76 最小覆盖子串(Hard)

题目来源:leetcode76 最小覆盖子串

题目描述:

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:

如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

解题思路:

滑动窗口的方法。参考labuladong题解思路

1、我们在字符串 s 中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个「窗口」。

2、我们先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的字符串符合要求(包含了 t 中的所有字符)。

3、此时,我们停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的字符串不再符合要求(不包含t 中的所有字符了)。同时,每次增加 left,我们都要更新一次最小子串长度的结果。

4、重复第 2 和第 3 步,直到 right 到达字符串 s 的尽头。

class Solution {
public:
    string minWindow(string s, string t) {
       int left=0,right=0,start=0,minLen=INT_MAX;
       map<char,int> window;
       map<char,int> needs;
       int i;
       for(i=0;i<t.size();i++)
        needs[t[i]]++;
       int match=0;
       while(right<s.size()){
           char c1=s[right];
           if(needs.count(c1)){
               window[c1]++;
               if(window[c1]==needs[c1]) match++;
           }
           right++;
           while(match==needs.size()){
               if(right-left<minLen){
                   start=left;
                   minLen=right-left;
               }
               char c2=s[left];
               if(needs.count(c2)){
                    window[c2]--;
                    if(window[c2]<needs[c2]) match--;
                }
                left++;
           }
       }
       return minLen==INT_MAX?"":s.substr(start,minLen);
    }
};
原文地址:https://www.cnblogs.com/yjcoding/p/13330116.html