-
滑动窗口字面意思就是这个窗口是移动的,也就是移动是按照一定方向来的。窗口大小并不是固定的,可以不断扩容直到满足一定的条件;也可以不断缩小,直到找到一个满足条件的最小窗口;当然也可以是固定大小。
-
滑动窗口实际上也算是双指针的应用,同样是由左右指针,右指针的作用是不断扩大窗口的范围,当窗口内的对象符合某个条件时,进行统计或者某种操作;然后左指针作用收缩窗口来打破条件,以便让右指针右移继续扩大窗口
-
滑动窗口的应用:
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
//特殊情况直接排除
if(s.empty()||words.empty())return {};
//存放结果的数组
vector<int> result;
//单词数组中的单词的大小,个数,以及总长度
int one_word=words[0].size();
int word_num=words.size();
int all_len=one_word*word_num;
//建立单词->单词个数的映射
unordered_map<string,int> m1;
for(const auto& w:words)m1[w]++;
for(int i=0;i<one_word;++i)
{
//left和rigth表示窗口的左右边界,count用来统计匹配的单词个数
int left=i,right=i,count=0;
unordered_map<string,int>m2;
//开始滑动窗口
while(right+one_word<=s.size())
{
//从s中提取一个单词拷贝到w
string w=s.substr(right,one_word);
right+=one_word;//窗口右边界右移一个单词的长度
if(m1.count(w)==0){//此单词不在words中,表示匹配不成功,然后重置单词个数、窗口边界、以及m2
count=0;
left=right;
m2.clear();
}
else{//该单词匹配成功,添加到m2中
m2[w]++;
count++;
while(m2.at(w)>m1.at(w))//一个单词匹配多次,需要缩小窗口,也就是left右移
{
string t_w=s.substr(left,one_word);
count--;
m2[t_w]--;
left+=one_word;
}
if(count==word_num)result.push_back(left);
}
}
}
return result;
}
};