滑动窗口
所有words中单词总长度一定,记ttlen。
在s中从下标 i 开始取ttlen个字符,统计每个单词出现的次数,如果和words一样,就把起始下标i加入答案。
记每个单词的长度为len,从i开始字符串和从i+len开始的字符串大部分是一样的,只是少了s[i+1,i+len),多了s[i+ttlen,i+ttlen+len)。
#include<unordered_map>
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ans;
if(words.size()==0||s.size()==0) return ans;
int ttlen = words.size()*words[0].size(), len = words[0].size();
if(ttlen>s.size()) return ans;
vector<unordered_map<string, int>> v;
unordered_map<string, int> mp1,mp2;
int tt =ttlen/len;
for(int i=0;i<len;++i){
if(i+ttlen-1>=s.size()) break;
for(int st=i;st<ttlen;st+=len)
++mp1[s.substr(st,len)];
v.push_back(mp1);
mp1.clear();
}
for(auto &wd:words) ++mp2[wd];
for(int i=0;i<v.size();++i){
if(v[i]==mp2) ans.push_back(i);
}
string tps;
int id;
for(int i=len;i+ttlen-1<s.size();++i){
tps = s.substr(i-len,len);
id = i%len;
if(v[id][tps]==1) v[id].erase(tps);
else --v[id][tps];
++v[id][s.substr(i+ttlen-len,len)];
if(v[id]==mp2) ans.push_back(i);
}
return ans;
}
};