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).
问题描述如上
解题:
先使用一个map(C++ 11中可以使用unordered_map)来保存每个单词在words中出现的次数,注意一个单词可能会出现多次。由于每个单词的长度相同,所以扫描窗口的长度为word_size * words.size()。
首先将窗口置于s的起始位置,将窗口截成一个个word长度的串,扫描这些串是否在前面保存的map中存在,并且出现的次数相同。如果存在且相同,那么表示找到了一个match。
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
map<string, int> record;
map<string, int> count;
vector<int> pos;
if (words.size() == 0)
{
return pos;
}
int word_size = (words[0]).size();
if (s.size() < word_size*words.size())
{
return pos;
}
for (int i=0; i<words.size(); i++)
{
if (record.find(words[i]) == record.end())
{
record[words[i]] = 1;
}else{
record[words[i]]++;
}
}
int i, j;
for (i=0; i< s.size()-word_size*words.size()+1 ; i++)
{
count.clear();
for (j=0; j<words.size(); j++)
{
string current_word = s.substr(i+j*word_size, word_size);
if (record.find(current_word) != record.end())
{
if (count.find(current_word) == count.end())
{
count[current_word] = 1;
}else{
count[current_word]++;
}
if (count[current_word] > record[current_word])
{
break;
}
}else{
break;
}
}
if (j == words.size())
{
pos.push_back(i);
}
}
return pos;
}
};