LeetCode-30. Substring with Concatenation of All Words
原创
©著作权归作者所有:来自51CTO博客作者ReignsDu的原创作品,请联系作者获取转载授权,否则将追究法律责任
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 words exactly once and without any intervening characters.
Example 1:
Input:s = "barfoothefoobarman",words = ["foo","bar"]
Output:[0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.
Example 2:
Input:s = "wordgoodgoodgoodbestword",words = ["word","good","best","word"]
Output:[]
题解:
暴力判断:
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
int n = words.size();
if (n == 0) {
return vector<int>();
}
int m = words[0].size();
if (s.length() < n * m) {
return vector<int>();
}
vector<int> res;
map<string, int> mp;
for (int i = 0; i < n; i++) {
if (mp.find(words[i]) == mp.end()) {
mp.insert(make_pair(words[i], 1));
}
else {
mp[words[i]]++;
}
}
for (int i = 0; i <= s.length() - m * n; i++) {
int k = i, cnt = 0;
string sub = s.substr(k, m);
map<string, int> data(mp);
while (data[sub] != 0) {
if (cnt == n - 1) {
res.push_back(i);
cnt = 0;
break;
}
data[sub]--;
k += m;
sub = s.substr(k, m);
cnt++;
}
}
return res;
}
};
滑动窗口:
记words中每个单词长度为m
以0 - m为起点,每次找m个单位大小,这样就能找完所有情况。
如果找到单词并且words[i]中有它并且没用完,cnt++,如果用完了,那就缩小窗口,找到第一个让它空余的最小左边界,如果cnt == n,即该窗口内所有words都出现了并且无多余,存储窗口的左边界。
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
if (s.empty() || words.empty()) {
return {};
}
vector<int> res;
int l = s.size(), n = words.size(), len = words[0].size();
unordered_map<string, int> m1;
for (int i = 0; i < n; i++) {
m1[words[i]]++;
}
for (int i = 0; i < len; ++i) {
int left = i, cnt = 0;
unordered_map<string, int> m2;
for (int j = i; j <= l - len; j += len) {
string t = s.substr(j, len);
if (m1.find(t) != m1.end()) {
m2[t]++;
if (m2[t] <= m1[t]) {
cnt++;
} else {
while (m2[t] > m1[t]) {
string tmp = s.substr(left, len);
m2[tmp]--;
if (m2[tmp] < m1[tmp]) {
cnt--;
}
left += len;
}
}
if (cnt == n) {
res.push_back(left);
m2[s.substr(left, len)]--;
cnt--;
left += len;
}
} else {
m2.clear();
cnt = 0;
left = j + len;
}
}
}
return res;
}
};