【刷题】滑动窗口入门

在这里插入图片描述
送给大家一句话:

那脑袋里的智慧,就像打火石里的火花一样,不去打它是不肯出来的。——莎士比亚

滑动窗口入门

  • 认识滑动窗口
  • Leetcode 209. 长度最小的子数组
    • 题目描述
    • 算法思路
  • Leetcode 3. 无重复字符的最长子串
    • 题目描述
    • 算法思路
  • Leetcode 1004. 最大连续1的个数 III
    • 题目描述
    • 算法思路
  • 总结
  • 送给大家一句话:
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见

今天我学习了滑动窗口的算法思路,接下来请与我一起看看吧!!!

认识滑动窗口

滑动窗口问题可以说是一种特殊的双指针问题,通常用于解决以下类型的问题:

  1. 连续子数组或子字符串问题:例如,找出一个数组中连续元素和最大或最小的子数组,或者在字符串中找到一个包含特定字符的最短子字符串。
  2. 固定窗口大小问题:当窗口大小固定时,我们可以通过移动窗口来遍历整个数组或字符串,并记录所需的统计信息。
  3. 可变窗口大小问题:在某些情况下,窗口的大小可能会根据特定条件而变化。这需要我们在遍历过程中动态地调整窗口的大小。

滑动窗口算法的基本思想是使用双指针(有时也可能使用更多指针)来表示窗口的边界。在每一步中,我们可以根据特定条件来移动窗口的边界,并更新所需的统计信息。

看这些定义是真无法想象出来哦怎么个滑动窗口的,下面我们一起来做题吧:

Leetcode 209. 长度最小的子数组

题目描述

在这里插入图片描述
看这个题目还是很好理解的,只需要我们找到和大于target的连续子数组,我们来看第一个样例target = 7, nums = [2,3,1,2,4,3] 显然4,3是最小的子数组。接下来分析一下算法思路:

算法思路

根据题目要求,首先可以想到的是暴力枚举算法(遇事不决,暴力解决),遍历穷举出所有的连续子数组,寻找满足要求的子数组,最终就找到了最小的连续子数组:

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
    	//暴力解法
        int n = nums.size();
        if (n == 0) {
            return 0;
        }
        //默认为最大值
        int ans = INT_MAX;
        //开始遍历
        for (int i = 0; i < n; i++) {
        //重置sum值
            int sum = 0;
            //判断子数组是否满足
            for (int j = i; j < n; j++) {
                sum += nums[j];
                if (sum >= s) {
                //满足就更新结果
                    ans = min(ans, j - i + 1);
                    break;
                }
            }
        }
        return ans == INT_MAX ? 0 : ans;
    }
};

这样暴力的算法的时间复杂度是O(n^2),我们看看可不可以进行优化:
来看图解(来着力扣官方)在这里插入图片描述

这样就模拟了滑动窗口:
做法:将右端元素划⼊窗⼝中,统计出此时窗⼝内元素的和:

  • 如果窗⼝内元素之和⼤于等于 target :更新结果,并且将左端元素划出去的同时继续判
    断是否满⾜条件并更新结果(因为左端元素可能很⼩,划出去之后依旧满⾜条件)
  • 如果窗⼝内元素之和不满⾜条件: right++ ,另下⼀个元素进⼊窗⼝。
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0,right = 0;
        //设置为最大值 保证没有满足的子数组时可以判断
        int len = INT_MAX;
        int sum = 0;
        sum += nums[left];

        while(left < nums.size() && right < nums.size()){
			//
            if(sum < target ){
                right++;
                if(right < nums.size())
                    sum += nums[right];

            }
            while (sum >= target){
                len = min (right - left + 1 , len) ;
                sum -= nums[left];
                left++;
            }
        }
        return len == INT_MAX ? 0:len;
    }
};

这样大大提高了算法的效率!!!
为何滑动窗⼝可以解决问题,并且时间复杂度更低?

  1. 这个窗⼝寻找的是:以当前窗⼝最左侧元素(记为 left1 )为基准,符合条件的情况。也就是在这道题中,从 left1 开始,满⾜区间和 sum >= target 时的最右侧(记为right1 )能到哪⾥。
  2. 我们既然已经找到从 left1 开始的最优的区间,那么就可以⼤胆舍去 left1 。但是如果继续像⽅法⼀⼀样,重新开始统计第⼆个元素( left2 )往后的和,势必会有⼤量重复的计算(因为我们在求第⼀段区间的时候,已经算出很多元素的和了,这些和是可以在计算下次区间和的时候⽤上的)。
  3. 此时, rigth1 的作⽤就体现出来了,我们只需将 left1 这个值从sum 中剔除。从right1 这个元素开始,往后找满⾜ left2 元素的区间(此时right1 也有可能是满⾜的,因为 left1 可能很⼩。 sum 剔除掉 left1 之后,依旧满⾜⼤于等于target )。这样我们就能省掉⼤量重复的计算。

这样我们不仅能解决问题,⽽且效率也会⼤⼤提升

继续我们来看下一题

Leetcode 3. 无重复字符的最长子串

题目描述

在这里插入图片描述
描述也是十分简单奥,我们接着来看如何解决

算法思路

首先想到的还是暴力枚举啊,我们可以借助哈希表来确定是否重复。
枚举过程中就会发现左右指针移动方向相同,所以可以进行滑动窗口

  1. 入窗口(右指针移动)
  2. 判断(判断是否需要移动左指针)
  3. 出窗口
  4. 更新结果
class Solution {
public:

    int lengthOfLongestSubstring(string s) {
        int len = 0;
        int n = s.size();
        //使用哈希进行判断是否重复
        int hash[128] = {0};
        int ret = 0;
        for(int left = 0,right = 0; right < n; right++){
       		//进入窗口
            hash[s[right]]++;
			//判断
            while(hash[s[right]] > 1){
            	//出窗口
                hash[s[left]]--;
                left++;
                len--;
            }
      		//更新结果
            len++;
            ret = max(len,ret);
        }
        return ret;

    }
};

这样就完美解决。
其实滑动窗口都是可以套用上面的模版的,不信?来看下一题

Leetcode 1004. 最大连续1的个数 III

题目描述

在这里插入图片描述
题目描述依然简单奥,只是判断条件发生了改变,我们需要来定义一个数字来比较是否满足少于k

算法思路

依旧是:

  1. 入窗口(右指针移动)
  2. 判断(判断是否需要移动左指针)
  3. 出窗口
  4. 更新结果
class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int tmp = 0,left = 0,right = 0,n = nums.size();
        int ret = 0;
        while(right < n){

            if(nums[right] == 0) {
                tmp++;    
            }

            while(tmp > k){
                if(nums[left] == 0) tmp--;
                left++;
            }

            ret = max(ret,right - left + 1);
            right++;
        }
        return ret;
    }
};

这样就成功完成解题!!!

总结

滑动窗口问题是可以通过模版来解决:

  1. 入窗口(右指针移动)
  2. 判断(按题分析判断是否需要移动左指针)
  3. 出窗口
  4. 更新结果

这样基本滑动窗口都可以解决,但重要的是理解滑动窗口的思路是如何得到的,是如何从暴力算法优化出来的。

送给大家一句话:

那脑袋里的智慧,就像打火石里的火花一样,不去打它是不肯出来的。——莎士比亚

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/471322.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python数据结构实验 顺序表的实现

一、实验目的 1&#xff0e;掌握用Python定义线性表的顺序存储类型&#xff1b; 2&#xff0e;掌握用Python调试顺序表的基本方法&#xff1b; 3&#xff0e;掌握顺序表的基本操作&#xff0c;插入、删除、查找、以及有序顺序表的合并等算法的实现&#xff1b; 二、实验环境…

首页效果炫酷的wordpress免费主题模板

视频背景免费WP主题 简洁大气的视频背景wordpress主题&#xff0c;找大视频背景的主题可以看看这个。 https://www.wpniu.com/themes/193.html 红色全屏大图WP主题 非常经典的一款免费wordpress主题&#xff0c;红色全屏大图满足多行业使用。 https://www.wpniu.com/themes…

sqli-labs训练平台靶场详解!!!!

sqli-labs 是一个专业的 SQL 注入练习平台,该平台包含常见的注入类型,环境共有65个 SOL 注入漏洞&#xff0c;旨在帮助Web安全学习者对SQL注入漏洞有一个全面的了解。 项目地址为:GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based…

JAVA多线程之同步

文章目录 1. wait/notify1.1 基本使用1.2 优化使用 2. Park & Unpark2.1 基本使用2.2 基本原理 3. 线程状态4. 活跃性4.1 死锁4.1.1 死锁介绍4.2.2 死锁定位 4.3 活锁4.4 饥饿 锁的使用&#xff0c;其实就是为了使用临界资源的时候来进行同步&#xff0c;即一个线程用完一个…

【哈希表】算法例题

目录 五、哈希表 39. 赎金信 ① 40. 同构字符串 ① 41. 单词规律 ① 42. 有效的字母异位词 ① 43. 字母异位词分组 ② 44. 两数之和 ① 45. 快乐数 ① 46. 存在重复元素 ① 47. 最长连续序列 ② 五、哈希表 39. 赎金信 ① 给你两个字符串&#xff1a;ransomNote 和 m…

MySQL中replace into详解、批量更新、不存在插入存在则更新、replace into的坑

文章目录 一、replace into原理二、replace into的三种形式三、replace into 使用案例3.1、replace into values3.1.1、只有主键且主键冲突3.1.2、有主键有唯一索引且主键冲突3.1.3、有主键有唯一索引且唯一索引冲突(有坑)3.1.4、有主键有唯一索引且与一条主键冲突与另一条唯一…

阿里云2核4g服务器支持多少人同时在线?意想不到

阿里云2核4G服务器支持多少人在线&#xff1f;阿里云服务器网账号下的2核4G服务器支持20人同时在线访问&#xff0c;然而应用不同、类型不同、程序效率不同实际并发数也不同&#xff0c;搭建网站的话支持日均2000IP访问。 阿里云2核4G服务器多少钱一年&#xff1f;2核4G5M带宽…

【Linux更新驱动、cuda和cuda toolkit】

目录 1. 更新显卡驱动1.1. 查看当前显卡驱动版本1.2. 删除原始显卡驱动1.3. 删除CUDA Toolkit1.4. 在NVIDIA官网找到2080Ti对应的最新驱动程序 2. 更新CUDA Toolkit2.1. 下载CUDA Toolkit2.2. 安装.run2.3. 添加环境变量2.4. 检查是否安装好了 最近需要更新服务器的显卡驱动和C…

AI助手 - 月之暗面 Kimi.ai

前言 这是 AI工具专栏 下的第四篇&#xff0c;这一篇所介绍的AI&#xff0c;也许是截至今天&#xff08;204-03-19&#xff09;国内可访问的实用性最强的一款。 今年年初&#xff0c;一直看到有人推荐 Kimi&#xff0c;不过面对雨后春笋般的各类品质的AI&#xff0c;说实话也有…

YOLOv9改进策略:卷积魔改 | AKConv(可改变核卷积),即插即用的卷积,效果秒杀DSConv | 2023年11月最新发表

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a; YOLOv9如何魔改卷积进一步提升检测精度&#xff1f;AKConv 通过不规则卷积运算完成高效特征提取的过程&#xff0c;为卷积采样形状带来更多探索选择。 AKConv可以作为即插即用的卷积运算来替代卷积运算来提高…

修复打印机不能打印的10种方法,总有一种适合你

前言 技术有时很奇怪,我们可以用声音控制恒温器,但有时打印机会像15年前一样令人困惑和不可靠。如果打印机向你抛出错误(或完全忽略你的要求),可能有许多原因。 不幸的是,仅仅找出问题才成功一半,另一半是解决方案,它将使你的打印机重新工作。下面是如何解决问题的方…

Mysql:行锁,间隙锁,next-key锁?

注&#xff1a;以下讨论基于InnoDB引擎。 文章目录 问题引入猜想1&#xff1a;只加了一行写锁&#xff0c;锁住要修改的这一行。语义问题数据一致性问题 猜想2&#xff1a;要修改的这一行加写锁&#xff0c;扫描过程中遇到其它行加读锁猜想3&#xff1a;要修改的这一行加写锁&…

STM32 CubeMx创建Lwip+FreeRtos时出现ping不通的问题

STM32 CubeMx创建LwipFreeRtos时出现ping不通 1、配置ETH&#xff0c;使用中断 2、配置Lwip&#xff08;使用静态ip&#xff09;&#xff0c;其余什么都不用管 3、配置FreeRtos&#xff08;选择V2版本&#xff09;&#xff0c;其余什么都不用管 4、创建代码 5、查看自动生…

python爬虫之xpath入门

文章目录 一、前言参考文档&#xff1a; 二、xpath语法-基础语法常用路径表达式举例说明 三、xpath语法-谓语表达式举例注意 四、xpath语法-通配符语法实例 五、选取多个路径实例 六、Xpath Helper安装使用说明例子&#xff1a; 七、python中 xpath 的使用安装xpath 的依赖包xm…

2024年 信息系统管理工程师(中级)

2024年信息系统管理工程师全套视频、历年真题及解析、历年真题视频解析、教材、模拟题、重点笔记等资料 1、2023、2022、2021、2020年全套教程精讲视频。 2、信息系统管理工程师历年真题及解析&#xff08;综合知识、案例分析&#xff09;、历年真题视频解析。 3、官方最新信…

有实际意义的伦敦金交易策略参考

一谈起有实际意义的伦敦金交易策略参考&#xff0c;很多人以为是讨论的是什么飞天遁地的技术&#xff0c;其实这些都是没有实际意义。对普通投资者来说&#xff0c;什么才是有实际意义的呢&#xff1f;那就是生存。要讨论实际有意义的伦敦金交易策略参考&#xff0c;就是投资者…

【赠书第21期】游戏力:竞技游戏设计实战教程

文章目录 前言 1 竞技游戏设计的核心要素 1.1 游戏机制 1.2 角色与技能 1.3 地图与环境 2 竞技游戏设计的策略与方法 2.1 以玩家为中心 2.2 不断迭代与优化 2.3 营造竞技氛围与社区文化 3 实战案例分析 4 结语 5 推荐图书 6 粉丝福利 前言 在数字化时代的浪潮中&…

ARM实验 LED流水灯

.text .global _start _start: 使能GPIOE GPIOF的外设时钟 RCC_MP_AHB4ENSETR的第[4][5]设置为1即可使能GPIOE GPIOF时钟 LDR R0,0X50000A28 指定寄存器地址 LDR R1,[R0] 将寄存器原来的数值读取出来&#xff0c;保存到R1中 ORR R1,R1,#(0x3<<4) 将第4位设置为1 S…

蓝桥杯需要掌握的几个案例(C/C++)

文章目录 蓝桥杯C/C组的重点主要包括以下几个方面&#xff1a;以下是一些在蓝桥杯C/C组比赛中可能会涉及到的重要案例类型&#xff1a;1. **排序算法案例**&#xff1a;2. **查找算法案例**&#xff1a;3. **数据结构案例**&#xff1a;4. **动态规划案例**&#xff1a;5. **图…

30天拿下Rust之错误处理

概述 在软件开发领域&#xff0c;对错误的妥善处理是保证程序稳定性和健壮性的重要环节。Rust作为一种系统级编程语言&#xff0c;以其对内存安全和所有权的独特设计而著称&#xff0c;其错误处理机制同样体现了Rust的严谨与实用。在Rust中&#xff0c;错误处理通常分为两大类&…