当前位置: 首页 > news >正文

【刷题】滑动窗口入门

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

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

滑动窗口入门

  • 认识滑动窗口
  • 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♪(・ω・)ノ谢谢阅读!!!

下一篇文章见

相关文章:

【刷题】滑动窗口入门

送给大家一句话&#xff1a; 那脑袋里的智慧&#xff0c;就像打火石里的火花一样&#xff0c;不去打它是不肯出来的。——莎士比亚 滑动窗口入门 认识滑动窗口Leetcode 209. 长度最小的子数组题目描述算法思路 Leetcode 3. 无重复字符的最长子串题目描述算法思路 Leetcode 1004…...

【Python 48小时速成 3】输入与输出

在 Python 中&#xff0c;输入和输出通常通过内置函数来实现。主要的输入函数是 input()&#xff0c;用于从用户获取输入&#xff0c;而输出函数则是 print()&#xff0c;用于将结果打印到控制台。以下是简单的代码示例演示了输入和输出&#xff1a; # 输入示例 name input(&…...

API开发小红书接口获得小红书笔记详情API接口请求接入演示

为了使用小红书的API接口获取笔记详情&#xff0c;你需要遵循以下步骤&#xff1a; 注册并登录开放平台&#xff0c;创建一个应用并获取App Key和App Secret。 使用App Key和App Secret获取访问令牌&#xff08;Access Token&#xff09;。 使用访问令牌&#xff08;Access T…...

Python条件语句深度解析:从基础到应用的全面指南

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4d8; 一、引言 &#x1f4dd; 二、…...

【leetcode热题】 地下城游戏

恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0…...

Centos7安装ffmpeg

Centos7安装ffmpeg 用到的包压缩并安装 用到的包 压缩并安装 tar xvJf ffmpeg-5.0.1.tar.xz yum install -y gcctar -zxvf yasm-1.3.0.tar.gz cd yasm-1.3.0 ./configure make && make install yasm --versionyum install -y bzip2tar jxvf nasm-2.14.02.tar.bz2 cd n…...

安卓面试题多线程 81-85

81. 共享变量在多线程下如何保证线程安全?因为多线程是交替执⾏,每个线程操作共享变量时可能会导致数据不⼀致,要确保线程 安全,需要在访问共享变量时添加同步机制。当然,如果这个变量本⾝是线程安全的,⽐如AtomicLong,那么多线程访问也是安全 的🚀🚀🚀🚀🚀�…...

Java基础知识总结(8)

StringBuilder类(是线程不安全的) StringBuffer 和 StringBuilder二者及其相似&#xff0c;下面是构造方法&#xff1a; StringBuilder StringBuilder()创建空对象&#xff0c;空的字符序列 StringBuilder StringBuilder(StringBuilder builder)传入对象创造字符序列 Strin…...

C++基础入门(命名空间,函数,引用)

文章目录 前言1,命名空间2,函数函数重载缺省参数内联函数 3,引用尾声 前言 欢迎来到这篇关于C的入门博客&#xff01;C是一门强大而又广泛应用的编程语言&#xff0c;作为一门面向对象的编程语言&#xff0c;C可以让你更好地组织和管理代码&#xff0c;提高代码的重用性和可维…...

【译】矢量数据库 101 - 什么是矢量数据库?

原文地址&#xff1a;Vector Database 101 - What is a Vector Database? 1. 简介 大家好——欢迎回到 Milvus 教程。在上一教程中&#xff0c;我们快速浏览了每天产生的日益增长的数据量。然后&#xff0c;我们介绍了如何将这些数据分成结构化/半结构化数据和非结构化数据&…...

Python Web开发记录 Day12:Django part6 用户登录

名人说:东边日出西边雨,道是无晴却有晴。——刘禹锡《竹枝词》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 1、登录界面2、用户名密码校验3、cookie与session配置①cookie与session②配置4、登录验证5、注销登录6、图片验证码①Pillow库②图片验证码的…...

SpringTask实现的任务调度与XXL-job实现的分布式任务调度【XXL-Job工作原理】

目录 任务调度 分布式任务调度 分布式任务调度存在的问题以及解决方案 使用SpringTask实现单体服务的任务调度 XXL-job分布式任务调度系统工作原理 XXL-job系统组成 XXL-job工作原理 使用XXL-job实现分布式任务调度 配置调度中心XXL-job 登录调度中心创建执行器和任务 …...

【java】图书管理系统

有了前几篇文章关于封装、继承、多态、接口等的介绍&#xff0c;想必各位读者对java面向对象的思想有了一定的认识。接下来这篇文章就让我们趁热打铁&#xff0c;利用所学知识做一个小项目图书管理系统吧 目录 一、图书类 1、book类 2、bookList类 二、功能实现 1、IOpera…...

C#实现约瑟夫环算法

目录 1.约瑟夫环定义 2.约瑟夫环算法实现需要注意的地方 3.通过一个例子来演示这个过程 4.三人的约瑟夫环示例 4.十二人的约瑟夫环示例 1.约瑟夫环定义 约瑟夫环即设有n个人坐成一个圈&#xff0c;从某个人开始报数&#xff0c;数到m的人出列&#xff0c;接着从出列的下一…...

游戏服务端配置“热更”及“秒启动”终极方案(golang/ygluu/卢益贵)

游戏服务端配置“热更”及“秒启动”终极方案 ygluu 卢益贵 关键词&#xff1a;游戏微服务架构、游戏服务端热更、模块化解耦、golang 目录 一、前言 二、异步线程加载/重载方案 三、配置表碎片化方案 四、指针间接引用 五、重载通知 六、示例代码 七、相关连接 一、…...

鸿蒙开发的入门

鸿蒙开发的入门 注册并实名认证华为开发者账户 华为官网 注册 有账户可以直接登录 并进行实名认证 下载并安装开发工具 鸿蒙开发使用的语言 java js c/c 仓颉 手机app java 硬件 c/c 应用开发工具的下载地址 Windows(64-bit) 下载地址 程序的运行过程 解析config.j…...

为什么要减少Http的请求以及如何减少Http请求

为什么要减少Http的请求 减少 HTTP 请求的数量是优化网页性能的一个重要策略&#xff0c;原因有以下几点&#xff1a; 1.延迟&#xff1a;每个 HTTP 请求都会有一定的网络延迟。即使数据量很小&#xff0c;请求和响应的往返时间也可能相当长&#xff0c;特别是在网络条件不好…...

Linux性能测试工具整理

性能测试工具&#xff1a;Unixbench lmbench stream iozone fio netperf spec2000 spec2006 一、unixbench unixbench主要是用于系统基础性能测试&#xff0c;unixbench也包含一些非常简单的2D和3D图形测试 UnixBench一个基于系统的基准测试工具&#xff0c;不单纯是CPU 内存 …...

前端路由history路由和hash路由的区别?原理?

前端路由是指在单页应用程序&#xff08;SPA&#xff09;中通过改变 URL 路径来实现页面切换和导航的机制。在前端开发中&#xff0c;有两种主要的前端路由实现方式&#xff1a;基于 History API 的路由&#xff08;history-based routing&#xff09;和基于哈希&#xff08;Ha…...

AcWing 727. 菱形——像拼图一样做题

题目描述] 分析&#xff1a; 利用程序根据输入的整数&#xff0c;画出由字符*构成的该整数阶的实心菱形。给出一个示例&#xff1a; n 7 n7 n7。 * * * * * * * * * * * * * * * * * * * * * * * * * 我们将采取拆解问题&#xff0c;通过四个部分的…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...