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

算法每日双题精讲——滑动窗口(长度最小的子数组,无重复字符的最长子串)

 🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟

别再犹豫了!快来订阅我们的算法每日双题精讲专栏,一起踏上算法学习的精彩之旅吧!💪


目录

💯前言

💯滑动窗口的作用

💯长度最小的子数组

 题目描述: 

⭐解题思路:

🙋这个解题思路是怎么来的呢?

 代码实现(以 C++ 为例):

👀复杂度分析:

💯无重复字符的最长子串

 题目描述: 

⭐解题思路:

🙋这个解题思路是怎么来的呢?

代码实现(以 C++ 为例):

👀复杂度分析:

💯总结


💯前言

在算法的领域中,滑动窗口算法犹如一把精巧的钥匙,能够高效地开启许多数组和字符串相关问题的求解之门。今日,我们将聚焦于两道经典题目 ——“长度最小的子数组” 和 “无重复字符的最长子串”,深入领略滑动窗口算法的魅力与应用技巧。

✍当面临在给定数据结构中查找满足特定条件的子结构问题时,滑动窗口算法常常能为我们提供清晰且高效的解题思路。


💯滑动窗口的作用

滑动窗口算法可有趣啦!它用两个同向的指针来定义一个会动的 “窗口” 哦,这个窗口就像一个调皮的😜小精灵,在数组或者字符串里跑来跑去呢。通过不停地调整窗口的大小和位置,它能时刻知道窗口里面元素的情况,这样就能很快找到我们想要的子序列或者子串啦。这种方法可比那种傻傻地把所有可能的子结构都检查一遍的暴力枚举法强多啦,它能让算法的效率像火箭一样🚀飞起来呢!

滑动窗口是利用单调性,用 “同向双指针” 来实现优化的哦。简单来说呢,就是指针只向前走,不会后退哦。

👇操作步骤大概是这样滴:

  1. 先把leftright都设成0
  2. 然后把元素放进窗口里,接着判断一下,如果满足条件就缩小窗口,如果不满足就扩大窗口,
  3. 最后别忘了更新结果哦。
  4. 就这样一直重复,直到把整个数据结构都遍历完。这样就能巧妙地避开那些没必要的计算啦,是不是很聪明呢?😎

💯长度最小的子数组

题目链接👉【力扣】

题目描述: 

给定一个包含 n 个正整数的数组和一个正整数 target,找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度。若不存在符合条件的子数组,则返回 0

⭐解题思路:
  1. 初始化双指针 left 和 right,均指向数组起始位置,sum 用于记录当前窗口内元素之和,初始化为 0minLength 记录最小子数组长度,初始化为一个较大值(如 INT_MAX)。
  2. 移动 right 指针向右扩展窗口,将新元素累加到 sum 中。
  3. 当 sum ≥ target 时,尝试移动 left 指针向右收缩窗口,同时更新 sum。在此过程中,不断比较当前窗口长度与 minLength,若当前长度更小,则更新 minLength
  4. 重复步骤 2 和 3,直到 right 指针到达数组末尾。
  5. 最后,若 minLength 仍为初始值,返回 0;否则,返回 minLength
🙋这个解题思路是怎么来的呢?

我们首先最容易想到解法一:暴力求解

👇现在我们来分析以下数组:

 起初我们让left=right=0,此时sum=2,(sum为left到right之间的和)

 sum=2 < target,我们让 right++,sum变成了2+3

 

当right走到这个位置时,sum=2+3+1+2=8>target,我们计算len=right-left ,然后让left++sum减去第一个left所指的值

sum<target,我们继续让 right++

重复以上步骤,记录最小的len,直到 right<n 

 代码实现(以 C++ 为例):
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size(); // 获取数组nums的大小int left = 0; // 滑动窗口的左边界指针,初始化为0int right = 0; // 滑动窗口的右边界指针,初始化为0int sum = 0; // 用于记录当前滑动窗口内元素的总和int len = INT_MAX; // 初始化为INT_MAX,用于记录满足条件的最小子数组长度// 开始移动右边界指针right来扩展滑动窗口while (right < n) {sum += nums[right]; // 将当前右边界指向的元素加入到总和sum中// 当当前滑动窗口内元素总和sum大于等于目标值target时while (sum >= target) {len = std::min(len, right - left + 1); // 更新最小子数组长度len,取当前窗口长度与之前记录的最小值中的较小值sum -= nums[left]; // 将窗口左边界对应的元素从总和sum中减去left++; // 左边界指针向右移动一位,尝试缩小窗口继续寻找更小的满足条件的子数组}right++; // 右边界指针向右移动一位,继续扩展窗口}// 如果len仍然是INT_MAX,说明没有找到满足条件的子数组,返回0;否则返回lenreturn len == INT_MAX? 0 : len;}
};
👀复杂度分析:
  • 时间复杂度:O(n),其中 n 为数组长度。最坏情况下,right 指针遍历整个数组一次,left 指针最多也遍历整个数组一次。
  • 空间复杂度:O(1),仅需额外常数级别的空间存储指针和变量。

💯无重复字符的最长子串

题目链接👉【力扣】

题目描述: 

给定一个字符串 s,找出其中不含有重复字符的最长子串的长度。

⭐解题思路:
  1. 初始化 left 和 right 指针指向字符串起始位置,使用 unordered_set<char> 来记录窗口内出现过的字符。
  2. 移动 right 指针向右扩展窗口,将新字符插入集合中。
  3. 若新插入字符已在集合中,说明出现重复,此时移动 left 指针向右收缩窗口,同时从集合中移除窗口左侧字符,直到窗口内无重复字符。
  4. 在每次移动指针后,更新无重复字符的最长子串长度。
  5. 重复步骤 2 - 4,直到 right 指针到达字符串末尾。
🙋这个解题思路是怎么来的呢?

 我们首先最容易想到解法一:暴力求解

👇现在我们来分析以下字符串:

left=right=0,创建哈希表

如果right不在hash里面,将right的值存在hash里面,right++

 

当right所指的值已经在哈希表里了,我们计算len=right-left

接着我们让 left 走到与 right 所指的值的后面 ,即a的后面

重复以上过程,找到最大的len,直到right<n 

代码实现(以 C++ 为例):
class Solution {
public:// 函数用于计算给定字符串s中的最长无重复字符子串的长度int lengthOfLongestSubstring(string s) {// 创建一个大小为128的数组,用于记录每个字符出现的次数,初始化为0// 假设字符串中的字符ASCII码值范围在0 - 127之间int hash[127 + 1] = {0}; int left = 0; // 滑动窗口的左边界指针,初始化为0int right = 0; // 滑动窗口的右边界指针,初始化为0int ret = 0; // 用于记录最长无重复字符子串的长度,初始化为0int n = s.size(); // 获取字符串s的长度// 开始移动右边界指针right来扩展滑动窗口while (right < n) {// 将右边界指针right指向的字符在hash数组中的计数加1hash[s[right]]++;// 当右边界指针right指向的字符出现次数大于1时,即出现重复字符while (hash[s[right]] > 1) {// 将左边界指针left指向的字符在hash数组中的计数减1,并将左边界指针left向右移动一位hash[s[left++]]--;}// 更新最长无重复字符子串的长度ret,取当前窗口长度(right - left + 1)与之前记录的ret中的较大值ret = std::max(ret, right - left + 1);right++; // 右边界指针right向右移动一位,继续扩展窗口}return ret; // 返回最长无重复字符子串的长度}
};
👀复杂度分析:
  • 时间复杂度:外层循环遍历字符串,内层循环虽可能多次执行但左、右边界指针总共移动次数最多为 2n 次,整体时间复杂度为O(n) ,n 是字符串长度。
  • 空间复杂度:仅用了固定大小的数组 hash 及几个固定占用空间的变量,空间复杂度为O(1) 。

💯总结

✍通过对这两道题目的深入剖析,我们深切体会到滑动窗口算法在处理数组和字符串问题时的高效性与灵活性。它通过巧妙维护窗口状态,避免了冗余计算,快速定位目标子结构。希望大家在后续算法学习中熟练掌握此算法,轻松应对类似挑战。


我将持续在算法领域深耕细作,为大家带来更多精彩的算法知识讲解与问题解析。欢迎大家关注我

👉【A Charmer】

相关文章:

算法每日双题精讲——滑动窗口(长度最小的子数组,无重复字符的最长子串)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#xff01;&#x1f4aa;…...

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST&#xff1f; > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放&#xff1f; 大流量 > 多个…...

STL - vector的使用和模拟实现

目录 一&#xff1a;vector的构造函数 二&#xff1a;vector的迭代器 三vector的空间增长问题 四&#xff1a;vector 增删查改接口 五&#xff1a;vector的模拟实现 &#xff08;一&#xff09;一些简单接口的实现&#xff1a; &#xff08;二&#xff09;一些复杂接口的…...

《鸿蒙生态:开发者的机遇与挑战》

一、引言 在当今科技飞速发展的时代&#xff0c;操作系统作为连接硬件与软件的核心枢纽&#xff0c;其重要性不言而喻。鸿蒙系统的出现&#xff0c;为开发者带来了新的机遇与挑战。本文将从开发者的角度出发&#xff0c;阐述对鸿蒙生态的认知和了解&#xff0c;分析鸿蒙生态的…...

【C++融会贯通】二叉树进阶

目录 一、内容说明 二、二叉搜索树 2.1 二叉搜索树概念 2.2 二叉搜索树操作 2.2.1 二叉搜索树的查找 2.2.2 二叉搜索树的插入 2.2.3 二叉搜索树的删除 2.3 二叉搜索树的实现 2.3.1 二叉搜索树的节点设置 2.3.2 二叉搜索树的查找函数 2.3.2.1 非递归实现 2.3.2.2 递…...

使用python-Spark使用的场景案例具体代码分析

使用场景 1. 数据批处理 • 日志分析&#xff1a;互联网公司每天会产生海量的服务器日志&#xff0c;如访问日志、应用程序日志等。Spark可以高效地读取这些日志文件&#xff0c;对数据进行清洗&#xff08;例如去除无效记录、解析日志格式&#xff09;、转换&#xff08;例如…...

如何查看本地的个人SSH密钥

1.确保你的电脑上安装了 Git。 你可以通过终端或命令提示符输入以下命令来检查&#xff1a; git --version 如果没有安装&#xff0c;请前往 Git 官网 下载并安装适合你操作系统的版本。 2.查找SSH密钥 默认情况下&#xff0c;SSH密钥存储在你的用户目录下的.ssh文件夹中。…...

本人认为 写程序的三大基本原则

1. 合法性 ‌定义‌&#xff1a;合法性指的是程序必须遵守法律法规和道德规范&#xff0c;不得用于非法活动。 ‌建议‌&#xff1a; ‌了解法律法规‌&#xff1a;在编写程序之前&#xff0c;了解并遵守所在国家或地区的法律法规&#xff0c;特别是与数据隐私、版权、网络安…...

A030-基于Spring boot的公司资产网站设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…...

React Hooks 深度解析与实战

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 React Hooks 深度解析与实战 React Hooks 深度解析与实战 React Hooks 深度解析与实战 引言 什么是 Hooks? 定义 为什么需要 Ho…...

#渗透测试#SRC漏洞挖掘#蓝队基础之网络七层杀伤链04 终章

网络杀伤链模型&#xff08;Kill Chain Model&#xff09;是一种用于描述和分析网络攻击各个阶段的框架。这个模型最初由洛克希德马丁公司提出&#xff0c;用于帮助企业和组织识别和防御网络攻击。网络杀伤链模型将网络攻击过程分解为多个阶段&#xff0c;每个阶段都有特定的活…...

计算机毕业设计Python+大模型农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

爬虫补环境案例---问财网(rpc,jsdom,代理,selenium)

目录 一.环境检测 1. 什么是环境检测 2.案例讲解 二 .吐环境脚本 1. 简介 2. 基础使用方法 3.数据返回 4. 完整代理使用 5. 代理封装 6. 封装所有使用方法 jsdom补环境 1. 环境安装 2. 基本使用 3. 添加参数形式 Selenium补环境 1. 简介 2.实战案例 1. 逆向目…...

SpringBoot有几种获取Request对象的方法

HttpServletRequest 简称 Request&#xff0c;它是一个 Servlet API 提供的对象&#xff0c;用于获取客户端发起的 HTTP 请求信息。例如&#xff1a;获取请求参数、获取请求头、获取 Session 会话信息、获取请求的 IP 地址等信息。 那么问题来了&#xff0c;在 Spring Boot 中…...

在 Windows 11 中使用 MuMu 模拟器 12 国际版配置代理

**以下是优化后的教学内容,使用 Markdown 格式,便于粘贴到 CSDN 或其他支持 Markdown 格式的编辑器中: 在 Windows 11 中使用 MuMu 模拟器 12 国际版配置代理 MuMu 模拟器内有网络设置功能,可以直接在模拟器中配置代理。但如果你不确定如何操作,可以通过在 Windows 端设…...

ASP.NET Core Webapi 返回数据的三种方式

ASP.NET Core为Web API控制器方法返回类型提供了如下几个选择&#xff1a; Specific type IActionResult ActionResult<T> 1. 返回指定类型&#xff08;Specific type&#xff09; 最简单的API会返回原生的或者复杂的数据类型&#xff08;比如&#xff0c;string 或者…...

SQL面试题——蚂蚁SQL面试题 连续3天减少碳排放量不低于100的用户

连续3天减少碳排放量不低于100的用户 这是一道来自蚂蚁的面试题目,要求我们找出连续3天减少碳排放量低于100的用户,之前我们分析过两道关于连续的问题了 SQL面试题——最大连续登陆问题 SQL面试题——球员连续四次得分 这两个问题都是跟连续有关的,但是球员连续得分的难…...

Python酷库之旅-第三方库Pandas(216)

目录 一、用法精讲 1011、pandas.DatetimeIndex.tz属性 1011-1、语法 1011-2、参数 1011-3、功能 1011-4、返回值 1011-5、说明 1011-6、用法 1011-6-1、数据准备 1011-6-2、代码示例 1011-6-3、结果输出 1012、pandas.DatetimeIndex.freq属性 1012-1、语法 1012…...

论文解析:计算能力资源的可信共享:利益驱动的异构网络服务提供机制

目录 论文解析:计算能力资源的可信共享:利益驱动的异构网络服务提供机制 KM-SMA算法 KM-SMA算法通过不断更新节点的可行顶点标记值(也称为顶标),利用匈牙利方法(Hungarian method)来获取匹配结果。在获取匹配结果后,该算法还会判断该结果是否满足Pareto最优性,即在没…...

Spring AOP技术

1.AOP基本介绍 AOP 的全称 (aspect oriented programming) &#xff0c;面向切面编程。 1.和传统的面向对象不同。 面向切面编程是根据自我的需求&#xff0c;将切面类的方法切入到其他的类的方法中。&#xff08;这么说抽象吧&#xff01;来张图来解释。&#xff09; 如图 传…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...