滑动窗口思路
利用双指针L和R,指示窗口的左边界和右边界,问题一般是问一个子串或子数组满足某些条件的时候子串/子数组的长度最大或最小。
- 初始时,L和R均位于下标0处,窗口大小为0;
- 开始扩展窗口,移动右指针R扩大窗口,使窗口满足题目的条件;
- 满足 题目条件后,移动左指针L,使得窗口满足题目要求的最大或最小
- 右指针R到达字符串/数组末尾后结束循环;
209. 长度最小的子数组
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int l=0,r=0,sum=0,ans=0x3f3f3f3f;
while(r<nums.size())
{
while(sum<target&&r<nums.size())
{
sum+=nums[r];
r++;
}
while(l<=r&&sum>=target)
{
sum-=nums[l];
if(r-l<ans)
ans=r-l;
//cout<<l<<" "<<r<<" "<<ans<<endl;
l++;
}
}
if(ans==0x3f3f3f3f)
ans=0;
return ans;
}
};
713. 乘积小于 K 的子数组
这题是统计满足条件的窗口内的子数组数量
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
int l=0,r=0,ans=0,mul=1;
while(r<nums.size())
{
mul*=nums[r];
while(mul>=k&&l<=r)
{
mul/=nums[l];
++l;
}
ans+=r-l+1;
++r;
}
return ans;
}
};