Problem:
You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in wordsexactly 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).
Analysis:
Solutions:
C++:
vector<int> findSubstring(string s, vector<string>& words)
{
map<string, int> candidates;
for(int i = 0; i < words.size(); ++i) {
if(candidates.find(words[i]) == candidates.end())
candidates[words[i]] = 1;
else
++candidates[words[i]];
}
int num_test_words = words.size();
int word_len = words[0].size();
vector<int> results;
for(int start = 0; start < (int)s.size() - num_test_words * word_len + 1; ++start) {
bool is_valid = true;
map<string, int> local_count;
int end = start + num_test_words * words[0].size() - 1;
for(int j = start; j <= end;) {
if(candidates.find(s.substr(j, word_len)) == candidates.end()) {
is_valid = false;
break;
} else if(local_count.find(s.substr(j, word_len)) != local_count.end()
&& candidates[s.substr(j, word_len)] == local_count[s.substr(j, word_len)]) {
is_valid = false;
break;
} else {
if(local_count.find(s.substr(j, word_len)) == local_count.end())
local_count[s.substr(j, word_len)] = 1;
else
++local_count[s.substr(j, word_len)];
j += word_len;
}
}
if(is_valid)
results.push_back(start);
}
return results;
}
Java:
Python: