【LeetCode】 子字符串思路

在一些求字串含有固定字符最短串,含有不同字符最长子串等问题中,利用 vector<int> map(128, 0)可以解决

题一:最短给定子串

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.
Seen this question in a real interview before?

思路:

利用map,将常用的128个ascall码都包含进去,然后将T里有的字符在map进行累加,并计数,然后在S里找子串,完全找到后计数为零,然后继续找,直到找到最短的子串。

class Solution {
public:
    string minWindow(string s, string t) {
        vector<int> map(128,0);
        int counter=t.size(), begin=0, end=0, min_length=INT_MAX, head = 0;
        for(auto a : t) map[a]++;
        while(end<s.size()){
            if(map[s[end++]]-- > 0) counter--;
            while(counter == 0){
                if(min_length > end - begin) min_length = end - (head = begin); 
                if(map[s[begin++]]++ == 0) counter++;                
            } 
        }
        return min_length == INT_MAX ? "" : s.substr(head, min_length);
    }
};

 

模板

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;
  }

根据模板就可以在不同的子串题中进行应用,也不是为了死搬硬套,这个只是利用map解决的思路,像递归解决排列问题一样。

题二:最长可出现两次子串

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;
    }

题三:最长无重复子串‘

输出长度

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;
    }

输出具体子串,这里加一个子串起始标志位就行,在更新长度时更新子串起始位就行

 

posted @ 2018-10-22 15:02  华不摇曳  阅读(302)  评论(0编辑  收藏  举报