本文参考https://www.cnblogs.com/ariel-dreamland/p/9134212.html
一开始的思路是使用递归做出words所有结合情况的字典
然后在s中截取words长度去查字典
结果超时了……
超时代码
class Solution {
public:
void dfs(vector<string>words, int chang, int step, vector<int>book,
string dd, unordered_map<string, int>&hash)
{
if (step == chang)
{
hash[dd] = 1;
return;
}
for (int i = 0; i < chang; i++)
{
if (book[i] == 0)
{
book[i] = 1;
dfs(words, chang, step + 1, book, dd + words[i], hash);
book[i] = 0;
}
}
return;
}
vector<int> findSubstring(string s, vector<string>& words) {
if(words.empty()||s.empty())
return {};
vector<int>re;
unordered_map<string, int>hash;
int c = s.size(), b = words.size();
int f = 0;
for (int i = 0; i < b; i++)
for (auto v : words[i])
f++;
vector<int>book;
for (int i = 0; i < b; i++)
book.push_back(0);
dfs(words, b, 0, book, "", hash);
for (int i = 0; i <= c - f; i++)
{
string st = s.substr(i, f);
if (hash.find(st) != hash.end())
re.push_back(i);
}
return re;
}
};
别人家的代码
不必做出所有情况
每次找出给定单词长度的子串,看其是否在第一个哈希表里,如果没有,则break,如果有,则加入第二个哈希表,但相同的词只能出现一次,如果多了,也break
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> res;
if (s.empty() || words.empty()) return res;
int n = words.size(), m = words[0].size();
unordered_map<string, int> m1;
for (auto &a : words) ++m1[a];//这里m1的值的初始值默认为0
for (int i = 0; i <= (int)s.size() - n * m; ++i) {
unordered_map<string, int> m2;
int j = 0;
for (j = 0; j < n; ++j) {
string t = s.substr(i + j * m, m);
if (m1.find(t) == m1.end()) break;
++m2[t];
if (m2[t] > m1[t]) break;
}
if (j == n) res.push_back(i);
}
return res;
}
};
围观大神代码
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
if (s.empty() || words.empty()) return {};
vector<int> res;
int n = s.size(), cnt = words.size(), len = words[0].size();
unordered_map<string, int> m1;
for (string w : words) ++m1[w];
for (int i = 0; i < len; ++i) {
int left = i, count = 0;
unordered_map<string, int> m2;
for (int j = i; j <= n - len; j += len) {
string t = s.substr(j, len);
if (m1.count(t)) {
++m2[t];
if (m2[t] <= m1[t]) {
++count;
} else {
while (m2[t] > m1[t]) {
string t1 = s.substr(left, len);
--m2[t1];
if (m2[t1] < m1[t1]) --count;
left += len;
}
}
if (count == cnt) {
res.push_back(left);
--m2[s.substr(left, len)];
--count;
left += len;
}
} else {
m2.clear();
count = 0;
left = j + len;
}
}
}
return res;
}
};