见到字串问题,首想滑动窗口。时间复杂度为O(n)。算法框架:
// window为滑动窗口,need为需要的字符,valid为目前窗口中满足条件的字符种类数目
unordered_map<char, int> window, need;
int left=0, right=0, valid=0;
for (char c:p) need[c]++;
while (right < s.size()) {
// 增大窗口
char c=s[right++];
// 加入的字符为需要的字符时,更新窗口和valid
if (need.count(c)) {
window[c]++;
if (window[c] == need[c]) {
valid++;
}
}
// 判断窗口是否要收缩,窗口定长时用if,否则用while
if (right-left > p.size()) {
char d=s[left++];
if (need.count(d)) {
// 注意:if要写在window[d]--前,否则有bug
if (window[d] == need[d])
valid--;
window[d]--;
}
}
}
//调试时,打印每步的window
void print_map(unordered_map<char, int> map) {
for(auto kv:map){
cout<<kv.first<<":"<<kv.second<<" ";
}
}