滑动窗口总结

前言

滑动窗口是双指针的一种特例,可以称为左右指针,在任意时刻,只有一个指针运动,而另一个保持静止。滑动窗口路一般用于解决特定的序列中符合条件的连续的子序列的问题。
好处:时间复杂度 O(n^2) ---> O(n)

一、算法应用场景

关键词:

1.满足XXX条件(计算结果、出现次数、同时包含)
2.最长/最短/或最值
3.子串/子数组/子序列
最最最重要的提示点是:必须是连续的,否则不可以用滑动窗口

二、滑动窗口代码模板

说明:理论上你可以设计两端都开或者两端都闭的区间,但设计为左闭右开区间是最方便处理的。因为这样初始化 left = right = 0 时区间 [0, 0) 中没有元素,但只要让 right 向右移动(扩大)一位,区间 [0, 1) 就包含一个元素 0 了。如果你设置为两端都开的区间,那么让 right 向右移动一位后开区间 (0, 1) 仍然没有元素;如果你设置为两端都闭的区间,那么初始区间 [0, 0] 就包含了一个元素。这两种情况都会给边界处理带来不必要的麻烦。

给出了两个滑动窗口的模板,并且又给出了求最长/最短/固定时的模板,并不是说有五个模板,其实后三个模板是嵌套在前两个中的,即后三个模板需要关注的是内层while的条件(窗口固定情况下时也可用while,但是if即可满足)以及最终结果result的更新位置。

希望你写滑动窗口时能有三问:

1、什么时候应该扩大窗口?

2、什么时候应该缩小窗口?

3、什么时候应该更新答案?

滑动窗口 + 变量计数模板

class Solution {
    public int slidingWindow(int[] nums, int k) {
        //数组/字符串长度
        int n = nums.length;
        //双指针,表示当前遍历的区间[left, right),左闭右开
        int left = 0, right = 0;
        //定义变量统计 子数组/子区间 是否有效
        int sum = 0;
        //定义变量动态保存最大 求和/计数
        int res = 0;
        //右指针遍历到数组尾
        while (right < n) {
            //增加当前右指针对应的数值
            sum += nums[right];
            //增加窗口,移动右指针,实现右开效果
            right++//当在该区间内 sum 超出定义范围
            while (sum > k) {
                //先将左指针指向的数值减去
                sum -= nums[left];
                //缩小窗口
                left++;
            }
            //到 while 结束时,我们找到了一个符合题意要求的 子数组/子串
            res = Math.max(res, right - left);
        }
        return res;
    }
}

滑动窗口 + 哈希表存储模板

class Solution {
    public String slidingWindow(String s, String t) {
        //创建两个哈希表,分别记录 [窗口] 和 [需要的]
        Map<Character, Integer> window= new HashMap<>();
        Map<Character, Integer> need= new HashMap<>();
        //创建 [双指针] 和 [有效数量]
        int left = 0, right = 0;
        int valid = 0;
        //外层循环,供右指针遍历
        while(right < s.length()){
            //创建临时 c 字符,是移入 窗口 内的字符
            char c = s.charAt(right);
            //增大窗口
            right++;
            //进行窗口一系列逻辑更新
            ...
            /*** debug 输出的位置 ***/
            //System.out.println("window: [" + left + "," + right + ")");

            //判断左指针是否要右移即窗口收缩:有效数量足够满足条件
             /*  可能是规定的窗口大小超出了,可能是有效值数量达成了
             1.  while(valid == need.size())
             2.  while(right - left >= s1.length())      
             */           
            while(windows need shrink){
                // 创建 d 是要移除窗口的字符
                char d = s.charAt(left);
                //缩小窗口
                left++;
                //进行窗口一系列逻辑更新
                ...
            }
        }
    }
}                    

寻找最长模板(while为窗口不满足条件,结果result在外部更新)

初始化 left,right,window,result
while("右指针没有到结尾"){
    窗口扩大,加入right对应元素,更新当前window
    right++;(right右移,起到左闭右开的效果,[left,right))
    while("window不满足要求"){
        窗口缩小,移除left对应元素,left右移
    }
    更新最优结果result
}
返回result

寻找最短模板(while为窗口满足条件,结果result在内部更新)

初始化 left,right,window,result
while("右指针没有到结尾"){
    窗口扩大,加入right对应元素,更新当前window
    right++;(right右移,起到左闭右开的效果,[left,right))
    while("window满足要求"){
        更新最优结果result
        窗口缩小,移除left对应元素,left右移
    }
}
返回result

窗口大小固定模板

初始化 left,right,window,result
while("右指针没有到结尾"){
    窗口扩大,加入right对应元素,更新当前window
    right++;(right右移,起到左闭右开的效果,[left,right))
    if("window达到固定值(right-left==target_length)"){
        if(满足条件){
            处理结果;
        }
        窗口缩小,移除left对应元素,left右移
    }
}
返回result    

 

原文链接:https://www.cnblogs.com/Co3y/p/17275580.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:滑动窗口总结 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • Python二元算术运算常用方法解析

    下面是详细讲解“Python二元算术运算常用方法解析”的完整攻略。 1. 什么是二元算术运算? 二元算术运算是指对两个数运算的操作,包括加法、减法、乘法、除法等。 2. Python二元算术运算常用方法 2.1 加法运算 加法运算是指将两个数相加的操作,可以使用加号(+)进行运算。 下面是一个加法运算的示例: a = 5 b = 3 c = a + b pr…

    python 2023年5月14日
    00
  • 数据结构串的操作实例详解

    数据结构串的操作实例详解 什么是数据结构串? 数据结构串是由若干个字符按照一定的顺序排列而成的线性结构。可以对串进行许多操作,如子串的截取、串的连接、串的替换等等。 数据结构串的基本操作 串的初始化 为了操作一个串,我们需要先定义一个串并初始化,可以通过以下代码实现: #include <stdio.h> #define MAXSIZE 100 …

    数据结构 2023年5月17日
    00
  • python 排序算法总结及实例详解

    Python排序算法总结及实例详解 排序算法是计算机科学中的基本问题之一,它的目的是将一组数据按照一定的顺序排列。在Python中,我们可以使用多种排序算法来对数据进行排序。本文将介绍常见的排序算法及其Python实现,并提供两个示例说明。 常见的排序算法 冒泡排序 冒泡排序是一种简单的排序算法,它的基本思想是通过不断交换相邻的元素,将较大的元素逐渐“冒泡”…

    python 2023年5月13日
    00
  • C语言植物大战数据结构快速排序图文示例

    C语言植物大战数据结构的快速排序可以分为以下步骤: 准备工作 首先需要定义一个关于植物大战中植物的结构体,例如: struct Plant { int hp; int atk; int cost; }; 然后准备一个装载植物信息的数组: struct Plant plants[] = { {75, 36, 100}, {100, 20, 50}, {125,…

    数据结构 2023年5月17日
    00
  • 「学习笔记」数位 DP

    「学习笔记」数位 DP 意义不大的题不写了。 点击查看目录 目录 「学习笔记」数位 DP 概述 例题 P2657 [SCOI2009] windy 数 思路 代码 P4317 花神的数论题 思路 P4124 [CQOI2016]手机号码 思路 代码 haha数 题意 思路 代码 0和1的熟练 题意 思路 代码 苍与红的试炼 题意 思路 代码 概述 数位 DP…

    算法与数据结构 2023年4月17日
    00
  • python实现决策树、随机森林的简单原理

    下面是详细讲解“Python实现决策树、随机森林的简单原理”的完整攻略。 1. 决策树 决策树是一种基于树结构的分类模型,它通过对集进行递归分割,最终生成一棵树结构,每个叶子节点代表一个类别。决策树的构建过程可以分为以下几个步骤: 选择最优特征作为根节点。 根据根节点特征将集分成多个子集。 对每个子集递归执行步骤1和步骤2,直到满停止条件。 构建决策树。 以…

    python 2023年5月14日
    00
  • Python实现常见的回文字符串算法

    以下是关于“Python实现常见的回文字符串算法”的完整攻略: 简介 回文字符串是指正着读和倒着读都一样的字符串。在本教程中,我们将介绍如何使用Python实现常见的回文字符串算法,并提供两个示例。 算法1:双指针法 双指针法是一种常见的回文字符串算法,它使用两个指针从字符串的两端开始扫描,如果两个指针指向的字符相同,则继续向中间移动,否则返回false。 …

    python 2023年5月14日
    00
  • 解析网站处理数据交换时的序列化和反序列化

    当网站处理数据交换时,数据往往要以一定的格式进行序列化和反序列化,以保证数据的传输和存储的正确性。本文将详细讲解如何解析网站处理数据交换时的序列化和反序列化。 什么是序列化和反序列化? 序列化(Serialization),简单来说就是将数据从一种特定的格式转换成字符串的过程。因此经过序列化后的数据可以通过网络传输或者存储到文件中,同时也可以减少数据传输过程…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部