Topic:
You is given a string, s, and a list of words, words, that is all of the same length. Find all starting indices of substring (s) in S that's a concatenation of each word in words exactly once and without any Intervening characters.
For example, given:
S"barfoothefoobarman"
Words["foo", "bar"]
You should return the indices: [0,9]
.
(Order does not matter).
Code:
classSolution { Public: Vector<int> findsubstring (stringS, vector<string>&words) {Vector<int>ret; if(Words.empty () | | s.empty ())returnret; Const intLen_w = words[0].size ();//length of substring in words Const intEnd = Words.size () *len_w;//Total length of words if(End>s.size ())returnRet//s size Not enoughmap<string,int>The Ori; for(intI=0; I<words.size (); ++i) {if(Ori.find (words[i]) = =Ori.end ()) {Ori[words[i]]=1; } Else{Ori[words[i]]++; }} Map<string,int>found; intMatch_num =0; intBegin =0; inti =0; while(i<s.size ()) { //cout << "I:" << i << Endl; //cout << "m:" << match_num << Endl; //cout << "begin:" << begin << Endl; //match one substring in words if(Ori.find (S.substr (i,len_w))! =Ori.end ()) {found[s.substr (i,len_w)]++; //substring occur more than times in words if(Found[s.substr (I,len_w)]>ori[s.substr (i,len_w)]) {found.clear (); Match_num=0; Begin++; I=begin; Continue; } I= i+Len_w; Match_num++; //cout << match_num << Endl; //match all substrings in words and push back a starting indices if(match_num==words.size ()) {Ret.push_back (i-end); Found.clear (); Begin++; I=begin; Match_num=0; } } //Not match Else{found.clear (); Match_num=0; Begin++; I=begin; } } returnret; }};
Tips
Use a double-pointer technique.
Maintain several key variables:
1. Begin: Possible valid starting position
2. Match_num: Number of words that have been matched
3. Each string in the Ori:words and the number of occurrences
4. Found: The current matched interval, each string in words, and the number of occurrences
The idea is that if a matching string,i is found, it jumps backwards, and there may be two things that can't be skipped during the jump:
A) The next fixed-length substring does not match.
b) The next fixed-length substring, although matched to one of the words, has exceeded the number of strings in the Ori
If you can not jump, the match_num and found will be zero, and need to go back to begin++ position, start a new round of search.
Here are a few details to note:
Direct use of found.clear () is possible, if one is zeroed, it will time out.
"Substring with concatenation of all Words" CPP