目录
438. 找到字符串中所有字母异位词
滑动窗口+哈希表
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
int len_s = s.size();
int len_p = p.size();
if(len_s < len_p)
return {};
vector<int> p_table(26,0);
vector<int> window_table(26,0);
for(int i = 0;i < len_p;i++){
p_table[p[i]-'a']++;
window_table[s[i]-'a']++;
}
vector<int> res;
if(p_table == window_table){
res.push_back(0);
}
for(int left = 0;left < len_s - len_p;left++){
window_table[s[left]-'a']--;
window_table[s[left+len_p] -'a']++;
if(window_table == p_table)
res.push_back(left+1);
}
return res;
}
};
30. 串联所有单词的子串
滑动窗口+哈希表
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
int s_len = s.size();
int word_cnt = words.size();
int word_len = words[0].size();
int window_len = word_cnt*word_len;
if(s_len < window_len)
return {};
unordered_map<string,int> words_table;
for(int i = 0;i < word_cnt;i++){
if(words_table.contains(words[i])){
words_table[words[i]]++;
}else{
words_table[words[i]]=1;
}
}
vector<int> res;
unordered_map<string,int> window_table;
//外层循环是对s做划分,例如:s = "barfoothefoobarman", words = ["foo","bar"]
//此时word_len是3,所以有3种划分方式
//对s从第一个字母开始划分为bar,foo,the,foo,bar,man
//对s从第二个字母开始划分为b,arf,oot,hef,oob,arm,an。最前面的b和最后面的an不需要考虑
//对s从第三个字母开始划分为ba,rfo,oth,efo,oba,rma,n。最前面的ba和最后面的n不需要考虑
for(int start = 0; start< word_len && s_len - start >= window_len;start++){
for(int i = 0;i < word_cnt;i++){
string temp = s.substr(start + i*word_len,word_len);
if(window_table.contains(temp))
window_table[temp]++;
else
window_table[temp]=1;
}
if(check(window_table,words_table))
res.push_back(start);
int current_left = start;
while(current_left < s_len - window_len){
string temp = s.substr(current_left,word_len);
window_table[temp]--;
if(window_table[temp] == 0)
window_table.erase(temp);
window_table[s.substr(current_left+window_len,word_len)]++;
if(check(window_table,words_table))
res.push_back(current_left+word_len);
current_left += word_len;
}
window_table.clear();
}
return res;
}
bool check(unordered_map<string,int> &window_table,unordered_map<string,int> &words_table){
for(const auto&[word,cnt] : words_table){
if(cnt != window_table[word])
return false;
}
return true;
}
};