1. 程式人生 > >LeetCode最小窗口子字符串以及求解子字符串模板

LeetCode最小窗口子字符串以及求解子字符串模板

一個數 max length http ring 子字符串 window date 備註

LeetCode原題地址

題幹:

給定字符串S和T,以O(n)復雜度在S中找出包含T中所有字符的最小窗口子字符串。

示例:

S = "ADOBECODEBANC"
T = "ABC"

最小窗口是"BANC".

備註:

如果沒有結果,返回空字符串""。

如果有多個窗口,保證只有一個最小解。

Discuss中的答案(並且給出了一個求解所有子字符串問題的模板):

原題的解:

 1 string minWindow(string s, string t) {
 2         vector<int> map(128,0);
 3         for(auto c: t) map[c]++;
4 int counter = t.size(), begin = 0, end = 0, d = INT_MAX, head = 0; 5 while(end<s.size()){ 6 if(map[s[end++]]-- > 0) counter--; //in t 7 while(counter == 0){ //valid 8 if(end - begin < d) d = end - (head = begin); 9 if(map[s[begin++]]++ == 0
) counter++; //make it invalid 10 } 11 } 12 return d==INT_MAX? "":s.substr(head, d); 13 }

上面的代碼要理解兩點:

1.自增語句,i++是i先不自加,在語句完後自加。

2.vector<int> map(128,0)可以理解為一個數組,也可以理解為對於可見的ASCII字符永遠不會沖突的hashmap

接下來是模板:

對於大多數子字符串問題,給定一個字符串,需要找到一個滿足某些條件的子字符串,通用的方法是使用一個hashmap和兩個指針(begin和end,此指針非彼指針)。

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

LeetCode最小窗口子字符串以及求解子字符串模板