题意
给定字符串s和单词集合words,words里面的所有word以任意顺序组合成一个新的字符串t,其中要求每个word出现且仅出现1次,问在组合字符串t是否是s的字串,若是,求出t在s开始的下标,题目要求求出所有满足要求的下标。
题解
window slide
代码
static int x=[](){
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
return 0;
}();
class Solution {
vector<int> primeSet;
int getNextPrime(){
if(primeSet.empty()){
primeSet.push_back(2);
return 2;
}
else if(primeSet.size() == 1){
primeSet.push_back(3);
return 3;
}
else{
int back = primeSet.back(), sqrt_r;
bool flag;
for(int i = back + 2; ;i += 2){
sqrt_r = sqrt(i);
flag = true;
for(int j = 1; j < primeSet.size() && primeSet[j] <= sqrt_r; ++j)
if(i % primeSet[j] == 0){
flag = false;
break;
}
if(flag) {
primeSet.push_back(i);
return i;
}
}
}
}
public:
vector<int> findSubstring(string s, vector<string>& words) {
if(words.empty()) return vector<int>();
int ts, count, L = words[0].size(), M = s.size() - L, len = words.size();
vector<int> res;
unordered_map<string, int> m;
int sum = 0, ans;
for(string &t : words){
if(!m.count(t)){
count = getNextPrime();
sum += count;
m[t] = count;
}
else
sum += m[t]; // get words sum value
}
string cur;
for(int i = 0; i < L; ++i){
ts = 0;
ans = i;
count = 0;
for(int j = i; j <= M; j += L){
cur = s.substr(j, L);
if(m.count(cur)){
ts += m[cur];
count++;
while(ts > sum){
ts -= m[s.substr(ans, L)];
ans += L;
count--;
}
if(count == len && ts == sum) {
res.emplace_back(ans);
ts -= m[s.substr(ans, L)];
ans += L;
count--;
}
}
else{
ts = 0;
count = 0;
ans = j + L; //update init index
}
}
}
return res;
}
};