LeetCode 76. Minimum Window Substring(Hard)

LeetCode 76. Minimum Window Substring(Hard)

求字符串子串问题模板

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = “ADOBECODEBANC”, T = “ABC”
Output: “BANC”
Note:
If there is no such window in S that covers all characters in T, return the empty string “”.
If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

class Solution {//Two-Pointers
public:
    string minWindow(string s, string t) {
        vector<int> map(128,0);//hash统计字符数量 char=(1,128)
        for(auto c:t) map[c]++;//统计字符串t中各字符数量
        int counter = t.size();//保证s的子区间中t的字符都存在
        int end=0,begin=0,head=0,d=INT_MAX;
        while(end<s.size()){
            if(map[s[end++]]-->0) counter--;//s中存在一个t中的字符,区间内剩余需要满足条件-1
            while(counter==0){//满足条件区间
                if(end-begin<d) //d表示最短子串长度,从head~end
                    d=end-(head=begin);
                if(map[s[begin++]]++==0)//如果当前s字符区间删去s[begin],则新区间不满足条件了
                    counter++;//重新移动end,begin,寻找下一满足条件区间,当前区间信息保存在head,head+d中
            }
        }
        return d==INT_MAX?"":s.substr(head,d); //若无满足条件区间返回空串,不然返回子串head~head+d
    }
};

For most substring problem, we are given a string and need to find a substring of it which satisfy some restrictions. A general way is to use a hashmap assisted with two pointers. The template is given below.

找子串问题模板:

int findSubstring(string s){
        vector<int> map(128,0);
        int counter; // check whether the substring is valid
        int begin=0, end=0; //two pointers, one point to tail and one  head
        int d; //the length of substring

        for() { /* initialize the hash map here */ }

        while(end<s.size()){

            if(map[s[end++]]-- ?){  /* modify counter here */ }

            while(/* counter condition */){ 
                 
                 /* update d here if finding minimum*/

                //increase begin to make it invalid/valid again
                
                if(map[s[begin++]]++ ?){ /*modify counter here*/ }
            }  

            /* update d here if finding maximum*/
        }
        return d;
  }

例子:

One thing needs to be mentioned is that when asked to find maximum substring, we should update maximum after the inner while loop to guarantee that the substring is valid. On the other hand, when asked to find minimum substring, we should update minimum inside the inner while loop.
The code of solving Longest Substring Without Repeating Characters is below:

int lengthOfLongestSubstring(string s) {
        vector<int> map(128,0);
        int counter=0, begin=0, end=0, d=0; 
        while(end<s.size()){
            if(map[s[end++]]++>0) counter++; 
            while(counter>0) if(map[s[begin++]]-->1) counter--;
            d=max(d, end-begin); //while valid, update d
        }
        return d;
    }

The code of solving Longest Substring with At Most Two Distinct Characters is below:

int lengthOfLongestSubstringTwoDistinct(string s) {
        vector<int> map(128, 0);
        int counter=0, begin=0, end=0, d=0; 
        while(end<s.size()){
            if(map[s[end++]]++==0) counter++;
            while(counter>2) if(map[s[begin++]]--==1) counter--;
            d=max(d, end-begin);
        }
        return d;
    }

猜你喜欢

转载自blog.csdn.net/qq_33539027/article/details/102496071