题目
substring-with-concatenation-of-all-words
算法
* 两个哈希表
O(n^2)
- 第一个哈希表,先将所有的单词存入,然后从开头遍历,停止条件是当前剩余字符个数小于单次集里所有字符的长度
- 定义第二个哈希表,每次找出给定单词的长度的子串,看是否在第一个哈希
- 但相同的单词只可以出现一次,否则break
* 一个词一个词的变量
O(n)
代码
* 哈希
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];
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;
}
};