Substring with Concatenation of All Words
You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
For example, given:
S: "barfoothefoobarman"
L: ["foo", "bar"]
You should return the indices: [0,9]
.
(order does not matter).
第一种简单的思路:
用两个map,一个map用于表示L中各个单词的数目,另一个map用于统计当前遍历S得到的单词的数目
从第0个,第1个,第2个位置开始遍历S串
统计得到的单词的数目,如果某个单词数目超出了L中该单词的数目,或者某个单词没有再L中出现,则重新从下一个位置开始统计
1 class Solution { 2 public: 3 vector<int> findSubstring(string S, vector<string> &L) { 4 5 if(L.size()==0) return vector<int>(); 6 7 int wordLen=L[0].size(); 8 9 map<string,int> wordCount; 10 11 int i,j; 12 for(i=0;i<L.size();i++) wordCount[L[i]]++; 13 14 15 vector<int> result; 16 map<string,int> counting; 17 18 for(i=0;i<(int)S.length()-wordLen*L.size()+1;i++) 19 { 20 counting.clear(); 21 for(j=0;j<L.size();j++) 22 { 23 string str=S.substr(i+j*wordLen,wordLen); 24 if(wordCount.find(str)!=wordCount.end()) 25 { 26 counting[str]++; 27 if(counting[str]>wordCount[str]) 28 { 29 break; 30 } 31 } 32 else 33 { 34 break; 35 } 36 } 37 38 if(j==L.size()) 39 { 40 result.push_back(i); 41 //i=i+L.size()*wordLen-1; 42 } 43 } 44 45 return result; 46 47 } 48 };
第二种思路,维护一个窗口,在遍历时分别要从0,1……wordLen开始遍历一遍,防止遗漏
如果发现某个单词不在L中,则从下一个位置开始,重新统计
如果发现某个单词出现的次数多了,则需从这个单词第一次出现位置的后面一位开始统计,并要剔除这个位置之前统计的一些结果
1 class Solution { 2 public: 3 vector<int> findSubstring(string S, vector<string> &L) { 4 5 if(L.size()==0) return vector<int>(); 6 7 int wordLen=L[0].size(); 8 9 map<string,int> wordCount; 10 11 int i,j; 12 for(i=0;i<L.size();i++) wordCount[L[i]]++; 13 14 15 vector<int> result; 16 map<string,int> counting; 17 18 19 int count=0; 20 int start; 21 22 for(i=0;i<wordLen;i++) 23 { 24 count=0; 25 start=i; 26 counting.clear(); 27 for(int j=i;j<S.length()-wordLen+1;j=j+wordLen) 28 { 29 string str=S.substr(j,wordLen); 30 31 if(wordCount.find(str)!=wordCount.end()) 32 { 33 counting[str]++; 34 count++; 35 if(counting[str]>wordCount[str]) 36 { 37 //更新start位于str第一次出现之后,更新counting,更新count 38 getNextIndex(start,str,counting,S,wordLen,count); 39 } 40 } 41 else 42 { 43 counting.clear(); 44 start=j+wordLen; 45 count=0; 46 } 47 48 if(count==L.size()) 49 { 50 result.push_back(start); 51 } 52 } 53 } 54 return result; 55 } 56 57 58 void getNextIndex(int &start,string str,map<string,int> &counting,string &S,int &wordLen,int &count) 59 { 60 for(int j=0;;j++) 61 { 62 string tmpStr=S.substr(start+j*wordLen,wordLen); 63 count--; 64 counting[tmpStr]--; 65 if(tmpStr==str) 66 { 67 start=start+(j+1)*wordLen; 68 break; 69 } 70 } 71 72 } 73 };