给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。
s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。
例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd","cdabef", "cdefab","efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。
返回所有串联字串在 s 中的开始索引。你可以以 任意顺序 返回答案。
输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。
子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。
解
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ans;
if(words.empty()) return ans;
int n =s.length(),m=words.size(), w= words[0].length();
unordered_map<string,int> total;
for(int i=0;i<words.size();i++){
total[words[i]]++;
}
for(int i=0;i<w;i++){
unordered_map<string,int> window;
int cnt =0;
for(int j=i;j+w<=n;j +=w){
if(j-i>=m*w){
string word = s.substr(j - m*w,w);
window[word]--;
if(window[word]<total[word]) cnt--;
}
string word = s.substr(j,w);
window[word]++;
if(window[word]<= total[word]) cnt++;
if(cnt == m){ ans.push_back(j -(m-1)*w);}
}
}
return ans;
}
};