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

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

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


目录

💯前言

💯滑动窗口的作用

💯长度最小的子数组

 题目描述: 

⭐解题思路:

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

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

👀复杂度分析:

💯无重复字符的最长子串

 题目描述: 

⭐解题思路:

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

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

👀复杂度分析:

💯总结


💯前言

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

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


💯滑动窗口的作用

滑动窗口算法借助两个同向指针来界定一个动态的 “窗口”,在数组或字符串上逐步滑动。通过不断调整窗口的大小和位置,实时监控窗口内元素的特性,从而快速定位到符合要求的子序列或子串。这种方法避免了对所有可能子结构的暴力枚举,显著提高了算法效率。


💯长度最小的子数组

题目链接👉【力扣】

题目描述: 

给定一个包含 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】

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HiveSQL 中判断字段是否包含某个值的方法

HiveSQL 中判断字段是否包含某个值的方法 在 HiveSQL 中&#xff0c;有时我们需要判断一个字段是否包含某个特定的值。下面将介绍几种常用的方法来实现这个功能。 一、创建示例表并插入数据 首先&#xff0c;我们创建一个名为employee的表&#xff0c;并插入一些示例数据&am…

vue2 - el-table表格设置动态修改表头

效果 代码 <template><el-card><!-- 搜索栏 --><Search :query

MySQL 8.0的Public Key Retrival问题解决

一、导致“Public Key Retrieval is not allowed”原因 该错误是在 JDBC 与 MySQL 建立 Connection 对象时出现的&#xff1b;需要明确的是出现该问题的时候&#xff0c;MySQL 配置的密码认证插件为如下两种&#xff1a; sha256_passwordcaching_sha2_password 使用“mysql_…

sed超实用的文本处理工具

sed命令参数表 sed参数说明a在指定行的后面增加新航c替换指定行d删除行-e多次编辑&#xff0c;多次编辑后这样写回文件。sed -i -e /^[[:space:]]*#/d -e /^$/d nginx.confp打印行-r激活拓展正则-n取消默认输出-i静默编辑&#xff0c;屏幕上不显示编辑后的内容&#xff0c;放在…

GPU 环境搭建指南:如何在裸机、Docker、K8s 等环境中使用 GPU

本文主要分享在不同环境&#xff0c;例如裸机、Docker 和 Kubernetes 等环境中如何使用 GPU。 跳转阅读原文&#xff1a;GPU 环境搭建指南&#xff1a;如何在裸机、Docker、K8s 等环境中使用 GPU 1. 概述 仅以比较常见的 NVIDIA GPU 举例&#xff0c;系统为 Linux&#xff0c;…

Vue中父组件通过v-model向子组件传对象参数

描述&#xff1a; Vue中父组件通过v-model向子组件传递一个对象&#xff0c;在子组件实现一个能够对object key-value进行编辑的组件封装。 父组件文件 <form-child v-model"configMap"></form-child>import formChild from /components/formchild.vue i…

mysql数据同步到sql server

准备工作 下载安装sql server express 2019 现在安装SSMS(连接数据库GUI) 安装ssms for mysql 需要注意的是在上面的步骤中首先需要根据指导安装mysql ODBC 设置express sa用户密码登录 --change password for login user "sa"Security > Logins > sa (rig…

如何解决企业业务流程分散的痛点

企业面临的一个普遍问题是业务流程的分散。业务流程分散不仅使得工作效率大幅下降&#xff0c;还增加了出错的风险&#xff0c;影响了企业的整体运营效率。因此&#xff0c;解决这一问题成为了许多企业亟需面对的挑战。 业务流程分散的原因 业务流程分散的根本原因&#xff0…

融入模糊规则的宽度神经网络结构

融入模糊规则的宽度神经网络结构 论文概述创新点及贡献 算法流程讲解模糊规则生成映射节点生成输出预测结果 核心代码复现main.py文件FBLS.py文件 使用方法测试结果示例&#xff1a;使用公开数据集进行本地训练准备数据数据输入模型进行训练实验结果 环境配置资源获取 本文所涉…

SQL常见语法

select * from student; select&#xff1a;选取 from&#xff1a;来源 *&#xff1a;所有栏位 select 姓名&#xff0c;班级&#xff0c;成绩 from students; 选取特定栏位 select 姓名&#xff0c;班级&#xff0c;成绩 from students limit 5;--限制显示拦数 select 姓…

贪心算法-汽车加油

这道题目描述了一个汽车旅行场景&#xff0c;需要设计一个有效的算法来决定在哪几个加油站停车加油&#xff0c;以便最小化加油次数。题目给出了汽车加满油后的行驶距离n公里&#xff0c;以及沿途若干个加油站的位置。我们需要找出一个方案&#xff0c;使得汽车能够完成整个旅程…

yarn报错`warning ..\..\package.json: No license field`:已解决

出现这个报错有两个原因 1、项目中没有配置许可证 在项目根目录package.json添加 {"name": "next-starter","version": "1.0.0",# 添加这一行"license": "MIT", }或者配置私有防止发布到外部仓库 {"priv…

【电子通识】TINA-TI中仿真波形如何配置自动分离曲线?

在实际的TIAN-TI使用中,我们仿真后,输出的波形一般都是叠加的形式输出的。比如下图所示: 有一些更多条曲线且曲线内容不同的仿真,叠加后会更让我们看不清。导致很不方便。 一般这时我们会 选择View->Separate outputs( 分开输出),就可以将不同波形分…

【数据结构】线性表——顺序表

文章目录 一、线性表二、顺序表2.1概念及结构2.2、顺序表接口实现2.2.1、顺序表的动态存储2.2.2、顺序表初始化2.2.3、检查空间判断进行增容2.2.4、顺序表尾插、尾删2.2.5、顺序表头插、头删2.2.6、顺序表查找2.2.7、顺序表在pos位置插入x2.2.8、顺序表删除pos位置的值2.2.9、顺…

【Matlab算法】MATLAB实现基于小波变换的信号去噪(附MATLAB完整代码)

MATLAB实现基于小波变换的信号去噪 结果图前言正文1. 小波变换理论基础1.1 小波变换的数学模型1.2 离散小波变换原理2. 信号去噪方法2.1 去噪算法流程2.2 阈值处理方法3. 核心函数解析3.1 wavedec函数3.2 wthresh函数代码实现4.1 信号生成4.2 小波变换去噪完整代码总结参考文献…

神经网络基础--什么是正向传播??什么是方向传播??

前言 本专栏更新神经网络的一些基础知识&#xff1b;这个是本人初学神经网络做的笔记&#xff0c;仅仅堆正向传播、方向传播进行了讲解&#xff0c;更加系统的讲解&#xff0c;本人后面会更新《李沐动手学习深度学习》&#xff0c;会更有详细讲解;案例代码基于pytorch&#xf…

函数式编程Stream流(通俗易懂!!!)

目录 1.Lambda表达式 1.1 基本用法 1.2 省略规则 2.Stream流 2.1 常规操作 2.1.1 创建流 2.1.2 中间操作 filter map distinct sorted limit ​编辑skip flatMap 2.1.3 终结操作 foreach count max&min collect anyMatch allMatch noneMatch …

AMD-OLMo:在 AMD Instinct MI250 GPU 上训练的新一代大型语言模型。

AMD-OLMo是一系列10亿参数语言模型&#xff0c;由AMD公司在AMD Instinct MI250 GPU上进行训练&#xff0c;AMD Instinct MI250 GPU是一个功能强大的图形处理器集群&#xff0c;它利用了OLMo这一公司开发的尖端语言模型。AMD 创建 OLMo 是为了突出其 Instinct GPU 在运行 “具有…

使用服务器时进行深度学习训练时,本地必须一直保持连接状态吗?

可以直接查看方法&#xff0c;不看背景 1.使用背景2. 方法2.1 screen命令介绍2.2 为什么要使用screen命令2.3 安装screen2.4 创建session2.5 查看session是否创建成功2.6 跳转进入session2.7 退出跑代码的session2.8 删除session 1.使用背景 我们在进行深度学习训练的时候&…

深入了解区块链:Web3的基础架构与发展

在数字时代的浪潮中&#xff0c;区块链技术正逐渐成为Web3的重要基础&#xff0c;重新定义互联网的结构和用户体验。Web3不仅是一个全新的网络阶段&#xff0c;更代表了一种去中心化的理念&#xff0c;强调用户主权和数据隐私。本文将深入探讨区块链在Web3中的基础架构、技术特…