滑动窗口算法

滑动窗口:


滑动窗口的作用

滑动窗口是计算机语言中重要的算法之一,主要用于处理连续的数组数据或者字符串数据,常用来提取数据中的子数组或者子串。

当然无论什么算法只要愿意去做和理解都不会太难,下面我就用JAVA语言来演示一下算法原型案例。
提示:以下是本篇文章正文内容,下面案例可供参考

一、滑动窗口案例-1

209.长度最短的子数组

class Solution {
    	public static int minSubArrayLen(int target, int[] nums) {
		int num = 0;	//计算子数组的累计和
		int min = nums.length;	//长度值赋初值
        boolean b=false;	//判断长度值是否改变过
		Queue<Integer> m = new LinkedList<Integer>();
		//定义队列,在我的理解中,队列是最能体现出滑动窗口特点的数据结构之一
		int i;
		for (i = 0; i < nums.length; i++) {
			if (num >= target) {
				min = Math.min(min, m.size());//求当前值和之前值中的最小值
                b=true;
				break;
			}
			m.offer(nums[i]);	//向队列m中添加数据nums[i]
			num += nums[i];
		} // 设置滑动窗口的初始长度
//第一个循环用于初始化滑动窗口的长度此时我们就已经有了一个长度为m.size()的窗口了
		while (num >= target || i < nums.length) { // 				如果已经将nums中的数据全都放入队列m中后,就可以进行筛选。
			if (num >= target) {
				min = Math.min(min, m.size());
                b=true;
				num -= m.poll();
//此时m中存放值的总和已经超过了目标值target,此时就突出了滑动窗口的特点了,此时我们的窗口已经满足的滑动的条件,如果现在num的值超过目标值就将前面先进入队列m的值踢出,就相当于窗口就向后移动了一步
			} else {
				num += nums[i];
				m.offer(nums[i++]);
			//如果此时不满足num>=target条件就继续向后延伸,向队列m中推入之后的值加到num中。
			}

		}
		if (!b)
			return 0;
		return min;
	}
}

经过这道题应该能大概明白滑动窗口是个什么东西了,就是先定义一组满足条件的数据使其成为一个窗口,再通过滑动这个窗口来满足我们需要的条件,我们处理的数据就是窗口中的数据

二、滑动窗户案例-2

567.字符串的排序

class Solution {
    public boolean checkInclusion(String s1, String s2) {
    int len1=s1.length(),len2=s2.length();
    char[] str1=s1.toCharArray();	//将字符串转为字符数组更好处理数据
    char[] str2=s2.toCharArray();
    int[] a1= new int[26]; 	//定义长度为26的整数数组a1、a2记录26个字母出现的次数
    int[] a2= new int[26];
    if(len1>len2)	//如果子串比主串长,直接退出
        return false;
    for(int i=0;i<26;i++)
        {a1[i]=0;
         a2[i]=0;}
    for(int i=0;i<len1;i++)
        {
            a1[str1[i]-'a']++;
            a2[str2[i]-'a']++;
        }
     //统计前len1个字母出现个数
     //此时也相当于创建了一个长度为len1的窗口
    if(Arrays.equals(a1,a2))
        return true;
     //用Arrays.equals(x1,x2)判断两个数组是否完全相等
    for(int i=len1;i<len2;i++)
    {a2[str2[i]-'a']++;
    a2[str2[i-len1]-'a']--;
    //此时开始通过上面两行代码进行滑动:
    	//a2[str2[i]-'a']++;   将新假如的字符转换成对应下标进行加减
    	//a2[str2[i-len1]-'a']--;  从头开始减去之前的数据
   if(Arrays.equals(a1,a2))//每次滑动都判断是否相等
        return true;}
    return false;
    }
}



案例原型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

总结

滑动窗口的使用方式:

  • 根据题目要求先设置窗口大小
  • 设置滑动范围
  • 滑动窗口
  • 退出

自我感觉滑动窗口的方式和队列的运行方式有很多相似的地方,就比如:

  • 根据题意设置队列大小 ------- 设置窗口大小
  • 队列先进先出的运行模式 ------- 窗口中的数据先进先出

但滑动窗口的特点是窗口可以是静态也可以是动态。

  • 案例一就是动态窗口,当选择值已经不能再改变的时候就可以通过动态改变窗口中的数据来判断是否是我们需要的值。
  • 案例二则是静态窗口,因为每道题的题意原因所以不能妄下定论说每个知识点的必然性。

滑动窗口的特点在于处理连续的数据多用于取 子数组和子串 子数组和子串的共同点在于他们的 连续性 都是连续处理的数据,所以滑动窗口算法将会判断处理完所有的数据之后才会得出答案。 因为滑动窗口算法需要判断完所有数据之后得出最优解,所以判断条件大多都是以数组或者字符串长度来定。

当理解了理论之后刷题自然是必不可少的:LeetCode力扣.滑动窗口专题

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值