滑动窗口的关键在与判断窗口滑动的条件,有时条件比较明显,例如本题,当窗口的值大于等于target时,窗口便需要移动,有时滑动的条件就没那么容易看出。
其中,判断是 right-left+1 还是 right-left 可以使用特例法:当窗口内只有一个元素
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n=nums.size();
int s=0;
int left=0,right=0;//同向双指针
int ans=n+1;
for(right=0;right<n;right++){//遍历数组
s+=nums[right];//向右拓展数组,计算窗口内值的和
while(s>=target){//如果窗口内数的和大于等于目标值
ans=min(ans,right-left+1);//更新最小长度
s-=nums[left];
left++;//滑动窗口的左边界右移,并且减去移除的值
}
}
ans=ans<=n?ans:0;
return ans;
}
};
和209题类似,窗口滑动的判断条件是窗口内数字相乘的乘积大于等于K
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
//l r
//[l,r] [l+1,r] [l+2,r]......[r,r]都是满足要求的子数组,数量为r-l+1
if(k<=1) return 0;
int n=nums.size();
int left=0,right=0;
int cnt=1;
int ans=0;
for(right=0;right<n;right++){
cnt*=nums[right];
while(cnt>=k){ //滑动条件
cnt/=nums[left];
left++;
}
ans+=right-left+1;//计算所满足的子数组的数量
}
return ans;
}
};
进阶
滑动窗口滑动的条件:当窗口内出现与当前字符相同的字符
unordered_set详情:C++ STL unordered_set容器完全攻略 (biancheng.net)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n=s.size();
if(n==0) return 0;
int left=0;
int right=0;
int res=0;
unordered_set<char>temp;
for(right=0;right<n;right++){
while(temp.find(s[right])!=temp.end()){//表示在窗口内找到了s[right]
temp.erase(s[left]);
left++;
}//如果出现相同字符,左端点就不断右移
res=max(res,right-left+1);
temp.insert(s[right]);//最后再进行插入
}
return res;
}
};