A few questions in the Leetcode use the same idea, basically maintaining a window, moving only the left or right edge of the window at a time, and then dealing with the elements within that window. Using two pointers in this way can reduce the run time of the problem to O (n).
Longest Substring without repeating characters:https://leetcode.com/problems/ longest-substring-without-repeating-characters/
This problem we maintain a window, each time the right side of the window to move one bit forward. In addition to maintaining a hash table, mark the position of the characters in the current window, once the right window encounters the characters in the current window, it shows that there are duplicates, move the left window to the next bit of the repeating character in the current window, and update the position of the repeating character to the position of the window. Each time the right window is moved, the current maximum length is updated, knowing that the window is moved to the last one.
The hash table here has a common use for strings, which is to declare an array of length 256, which corresponds to exactly 256 characters.
1 classSolution {2 Public:3 intLengthoflongestsubstring (strings) {4vector<int> Visit ( the, -1);5 intStart =0, end =0, Len =0;6 while(End <s.length ()) {7 if(Visit[s[end]] >=start) {8Start = Visit[s[end]] +1;9 }TenVisit[s[end]] =end; OneLen = max (end +1-start, Len); Aend++; - } - returnLen; the } -};View Code
Substring with concatenation of all words leetcode:https://leetcode.com/problems/ substring-with-concatenation-of-all-words/
The idea of this problem is also to maintain a window and hash table. However, due to the particularity of this problem, it is necessary to maintain two hash, one can not change the hash, used to store the dictionary, and the other is the change, is used to store the current window access to the word and the number of times each word.
In order for the algorithm to run in O (n) time, there is also a technique (which is also the reason for making the problem more difficult), assuming that the length of the source string is n, and that the length of the word in the dictionary is Wlen. Because it is not a character, we need to judge all substrings of the source string that are wlen in length. The procedure is I start from 0 to wlen-1 characters, get the initial inspection end for I, I+wlen, I+2*wlen, ... The length of the Wlen word. This ensures that all strings satisfying the condition are judged. Because the time complexity of each scan is O (2*n/wlen) (each word will not be accessed more than two times, one time is the right end of the window, once the left side of the window), a total of scan L times (i=0, ..., wlen-1), so the total complexity is O (2*n/l*l) =o (n), is a linear algorithm.
1 classSolution {2 Public:3vector<int> findsubstring (stringS, vector<string>&words) {4unordered_map<string,int>stable_dict;5 for(inti =0; I < words.size (); i++) {6 if(Stable_dict.find (words[i]) = =stable_dict.end ())7Stable_dict.insert (Make_pair (words[i),1));8 Else9stable_dict[words[i]]++;Ten } Onevector<int>Res; A intWlen = words[0].size (); - inti =0; - while(I <Wlen) { the intEnd =i; - intStart =i; - intCount =0; -unordered_map<string,int>dict; + while(End <s.length ()) { - stringCur =s.substr (end, Wlen); + stringStart_cur =s.substr (Start, wlen); A if(Stable_dict.find (cur)! =Stable_dict.end ()) { at if(Dict.find (cur) = =dict.end ()) -Dict.insert (Make_pair (cur,0)); - if(Dict[cur] <Stable_dict[cur]) { -dict[cur]++; -count++; -End + =Wlen; in } - Else { to if(Count = =words.size ()) + res.push_back (start); -dict[start_cur]--; thecount--; *Start + =Wlen; $ }Panax Notoginseng } - Else { theEnd + =Wlen; +Count =0; AStart =end; the dict.clear (); + } - } $i++; $ } - returnRes; - } the};View Code
Minimum Window substring:https://leetcode.com/problems/minimum-window-substring/
The idea of the problem is very similar to the previous. The difference is that the right pointer is shifted to the right for Each loop, and the condition for moving the left pointer is that when all the characters in the dictionary are in the window, the condition that the move is stopped is that there are no characters in the window. One thing to note here is that since we have taken a record of the number of characters in the dictionary that appear in the window, you should let the left pointer move if the number of characters is more than the number in the dictionary, and reduce the value until the number of characters in the dictionary is as many as possible.
1 classSolution {2 Public:3 stringMinwindow (stringSstringt) {4 stringres ="";5 intStart =0, end =0;6 intCount =0;7vector<int> Record ( the,0);8vector<int> Dict ( the,0);9 for(inti =0; I < t.length (); i++) {Tendict[t[i]]++; One } A while(End <s.length ()) { - if(Dict[s[end]) >0) { -record[s[end]]++; the if(Record[s[end]] <=Dict[s[end]]) { -count++; - } - if(Count = =t.length ()) { + while(Dict[s[start]] = =0|| Record[s[start]] >Dict[s[start]]) { -record[s[start]]--; +start++; A } atres = res.length () = =0? S.substr (Start, End +1-start): Res.length () < (end +1-start)? Res:s.substr (Start, End +1-start); -record[s[start]]--; -count--; -start++; - } - } inend++; - } to returnRes; + } -};View Code
It can be seen that this type of window is actually a double-pointer scan, the key point is to determine the movement of two pointers and the use of hash table to save the window information.
Several issues related to maintenance windows in Leetcode