[LeetCode] Substring with Concatenation of All Words
I think the following code is self-explanatory enough. We use an unordered_map<string, int> counts
to record the expected times of each word and another unordered_map<string, int> seen
to record the times we have seen. Then we check for every possible position of i
. Once we meet an unexpected word or the times of some word is larger than its expected times, we stop the check. If we finish the check successfully, push i
to the result indexes
.
1 class Solution { 2 public: 3 vector<int> findSubstring(string s, vector<string>& words) { 4 unordered_map<string, int> counts; 5 for (string word : words) 6 counts[word]++; 7 int n = s.length(), num = words.size(), len = words[0].length(); 8 vector<int> indexes; 9 for (int i = 0; i < n - num * len + 1; i++) { 10 unordered_map<string, int> seen; 11 int j = 0; 12 for (; j < num; j++) { 13 string word = s.substr(i + j * len, len); 14 if (counts.find(word) != counts.end()) { 15 seen[word]++; 16 if (seen[word] > counts[word]) 17 break; 18 } 19 else break; 20 } 21 if (j == num) indexes.push_back(i); 22 } 23 return indexes; 24 } 25 };
The following is a more sophisticated solution taken from this link. You may need to spend some time understanding how it works.
1 class Solution { 2 public: 3 vector<int> findSubstring(string s, vector<string>& words) { 4 int n = s.length(), len = words[0].length(), num = words.size(); 5 unordered_map<string, int> counts; 6 for (string word : words) 7 counts[word]++; 8 vector<int> indexes; 9 for (int i = 0; i < len; i++) { 10 int left = i, valid = 0; 11 unordered_map<string, int> seen; 12 for (int j = i; j <= n - len; j += len) { 13 string word = s.substr(j, len); 14 if (counts.find(word) != counts.end()) { 15 seen[word]++; 16 if (seen[word] <= counts[word]) 17 valid++; 18 else { 19 while (seen[word] > counts[word]) { 20 string wd = s.substr(left, len); 21 seen[wd]--; 22 if (seen[wd] < counts[wd]) valid--; 23 left += len; 24 } 25 } 26 if (valid == num) { 27 indexes.push_back(left); 28 seen[s.substr(left, len)]--; 29 valid--; 30 left += len; 31 } 32 } 33 else { 34 seen.clear(); 35 valid = 0; 36 left = j + len; 37 } 38 } 39 } 40 return indexes; 41 } 42 };