# 串联所有单词的子串
给定一个字符串 s 和一些长度相同的单词 words。找出 s
中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
示例 1:
输入: s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。输出的顺序不重要, [9,0] 也是有效答案。
示例 2:
输入: s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
以下错误的选项是?
## aop
### before
```cpp
#include
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
vector res;
string s = "barfoothefoobarman";
vector words{"foo", "bar"};
res = sol.findSubstring(s, words);
for (auto i : res)
cout << i << " ";
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
vector findSubstring(string s, vector &words)
{
if (words.empty() || s.empty())
return {};
vector ans;
int len = words[0].length(), n = words.size(), total = n * len;
;
int l = s.length();
unordered_map list;
int i, j, left;
for (i = 0; i < n; i++)
list[words[i]]++;
for (i = 0; i <= l - total; i++)
{
unordered_map window;
bool flag = true;
left = i;
string str;
while (left - i < total)
{
str = s.substr(left, len);
if (list.count(str) == 1 && window[str] != list[str])
{
window[str]++;
left += len;
}
else
{
flag = false;
}
}
if (flag)
ans.push_back(i);
}
return ans;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
vector findSubstring(string s, vector &words)
{
vector res;
if (s.empty() || words.empty())
{
return res;
}
unordered_map ht;
for (const auto &w : words)
{
ht[w]++;
}
int len = words[0].length();
for (int i = 0, j = 0; i < s.length() - words.size() * len + 1; i++)
{
unordered_map counting;
for (j = 0; j < words.size(); j++)
{
string word = s.substr(i + j * len, len);
if (++counting[word] > ht[word])
{
break;
}
}
if (j == words.size())
{
res.push_back(i);
}
}
return res;
}
};
```
### B
```cpp
class Solution
{
public:
vector findSubstring(string s, vector &words)
{
if (words.empty() || s.empty())
return {};
vector ans;
unordered_map umap1;
unordered_map umap2;
int count = 0;
int left = 0;
for (string str : words)
++umap1[str];
int len = words[0].size();
int slen = s.size();
for (int i = 0; i < len; i++)
{
left = i;
count = 0;
umap2.clear();
for (int j = i; j <= slen - len; j += len)
{
string temp = s.substr(j, len);
if (umap1.count(temp))
{
umap2[temp]++;
count++;
while (umap2[temp] > umap1[temp])
{
string temp2 = s.substr(left, len);
--umap2[temp2];
--count;
left += len;
}
if (count == words.size())
{
ans.push_back(left);
--umap2[s.substr(left, len)];
--count;
left += len;
}
}
else
{
umap2.clear();
count = 0;
left = j + len;
}
}
}
return ans;
}
};
```
### C
```cpp
class Solution
{
public:
vector findSubstring(string s, vector &words)
{
vector result;
if (words.size() == 0 || s.length() == 0)
return result;
map words_map;
int word_len = words[0].length();
int word_num = words.size();
if (word_len > s.length())
return result;
for (vector::iterator it = words.begin(); it != words.end(); it++)
{
if (words_map.count(*it))
words_map[*it]++;
else
words_map[*it] = 1;
}
for (int i = 0; i < word_len; i++)
{
int left = i, right = i;
int cur_num = 0;
map s_map;
string right_str, left_string;
while (right <= s.length() - word_len)
{
right_str = s.substr(right, word_len);
if (!words_map.count(right_str))
{
right += word_len;
left = right;
cur_num = 0;
s_map.clear();
}
else
{
if (!s_map.count(right_str))
s_map.insert(pair(right_str, 1));
else
s_map[right_str] += 1;
cur_num += 1;
right += word_len;
if (s_map[right_str] > words_map[right_str])
{
while (s_map[right_str] > words_map[right_str])
{
string left_str = s.substr(left, word_len);
s_map[left_str]--;
cur_num--;
left += word_len;
}
}
if (cur_num == word_num)
{
result.push_back(left);
s_map[s.substr(left, word_len)]--;
left += word_len;
cur_num--;
}
}
}
}
return result;
}
};
```