leetcode 209 3 滑动窗口

 1 class Solution {
 2 public:
 3     int minSubArrayLen(int s, vector<int>& nums)
 4     {
 5         int l=0,r=-1;          //由于数组是[]区间,所以这样使之不包含任何元素
 6         int res=nums.size()+1;    //记录长度
 7         int sum=0;          //记录子数组的和
 8         while(l< nums.size())    //滑动过程,每一次while都走一步
 9         {
10 
11             if(r+1<nums.size()&&sum<s)//同时保证有边界到底后不再继续拓展
12                 sum+=nums[++r];
13             else
14                 sum-=nums[l++];
15 
16             if(sum>=s)          //每步生成子数组都判断条件
17                 res=min(res,r-l+1);
18         }
19         if(res==nums.size()+1) return 0;//没有更新,就是无解,就返回0
20         else return res;
21     }
22 };

这是一道与连续子数组相关的问题,如果尝试用暴力求解,每次遍历得到子数组,则是O(n^3)。

 

为什么考虑用滑动窗口?

因为滑动窗口能不遗漏的获取连续子数组(这里的连续很关键),并且,如果窗口步长为1,则可以对每一种情况都进行条件判断,随时更新。

具体实现思路:

  1. 对于某一子数组[i,j],考虑其内部元素是否达到要求,未达到要求,则扩大数组,考虑到数组应是从头开始的,所以扩张时是对j扩张,每一次扩张都获得一个新子数组,之后进行子数组条件判断,只要没达到要求,就再扩张j,直到达到要求。
  2. 倘若达到要求了,那么记录下这一长度。可是单纯达到要求还不够呀,因为我们要的是对所有的连续子数组进行遍历查看。
  3. 于是保持j不变,使i++,这样获得了一个新的子数组,重复子数组条件判断,仍然满足要求,则更新长度,若没有满足要求了,就又回到1.

总结:

  简单来说,滑动窗口就是一种以单步走保证每种情况不遗漏的解法,最后时间复杂度只是O(n)(正比于走的路子2n)。

 

再来看leetcode 3。

 1 class Solution {
 2 public:
 3     int lengthOfLongestSubstring(string s)
 4     {
 5         int freq[256]={0};
 6         int l=0,r=-1;
 7         int res=0;
 8         while(l<s.size())
 9         {
10             if(r+1<s.size() && freq[s[r+1]]==0)
11             {
12                 r++;
13                 freq[s[r]]++;
14             }
15             else
16             {
17                 freq[s[l++]]--;
18             }
19 
20             res=max(res,r-l+1);
21         }
22         return res;
23     }
24 };

可以看出,滑动窗口的模板是相对比较固定的。

对于一个滑动窗口,最大的循环是while(l<s.size()),是为了使得左边界也到达最大。之后是if(r+1<s.size() && freq[s[r+1]]==0),前半边是为了右边界在达到最大时不再继续扩张。

而这一if else循环是为了变动滑动窗口。

转载于:https://www.cnblogs.com/IaCorse/p/10897596.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值