coding ability 展开第三幕(滑动指针——基础篇)超详细!!!!

文章目录
- 前言
- 滑动窗口
- 长度最小的子数组
- 思路
- 无重复字符的最长子串
- 思路
- 最大连续1的个数
- 思路
- 将x减到0的最小操作数
- 思路
- 总结
前言
前面我们已经把双指针的一些习题练习的差不多啦
今天我们来学习新的算法知识——滑动窗口
让我们一起来探索滑动窗口的魅力吧
滑动窗口
滑动窗口算法(Sliding Window Algorithm)是一种用于处理数组、字符串等线性数据结构的高效算法。它通过维护一个动态的窗口来优化计算过程。滑动窗口的核心思想是通过逐步移动窗口来获得所需的结果,而不是每次都从头开始重新计算。这个方法能够减少时间复杂度,从而提高算法效率。
滑动窗口算法的基本思想
滑动窗口算法分为两个主要类型:
1.固定大小窗口(Fixed-size Sliding Window):窗口的大小在整个过程中保持不变。
2.可变大小窗口(Variable-size Sliding Window):窗口的大小可以根据需求变化,通常是通过扩展或收缩窗口来满足特定条件。
滑动窗口的工作原理
1.初始化窗口:在数据结构的开始处创建一个窗口,并根据问题的需要选择适当的大小。
2.移动窗口:窗口通常从左到右(或其他方向)滑动,每次滑动时,更新窗口内的信息。
3.计算或更新结果:每次移动窗口时,计算窗口内的相关信息,通常是某种聚合值(如求和、最大值等)。
滑动窗口的应用场景
滑动窗口算法常用于以下几种常见问题中:
1.最大子数组和问题:给定一个整数数组,找到其所有连续子数组的和的最大值。
2.无重复字符的最长子串:给定一个字符串,找到其中没有重复字符的最长子串的长度。
3.最小覆盖子串:给定一个字符串和一个字符集合,找到覆盖所有字符的最小子串。
4.固定大小子数组的滑动:找到所有固定大小的子数组中,和最大的子数组。
实践是检验真理的唯一标准,一起来刷题吧
长度最小的子数组

思路
首先想到的肯定是暴力解法:
「从前往后」枚举数组中的任意一个元素,把它当成起始位置。然后从这个「起始位置」开始,然后寻找一段最短的区间,使得这段区间的和「大于等于」目标值。将所有元素作为起始位置所得的结果中,找到「最小值」即可。
不用多说,超时是必然的。
这题分析的对象时一段连续的区间,由此我们想到可以试试滑动窗口来解决
让滑动窗口满足:从 i 位置开始,窗口内所有元素的和小于 target (那么当窗口内元素之和第一次大于等于目标值的时候,就是 i 位置开始,满足条件的最小长度)
每一次将右端元素划入窗口,然后统计出窗口内元素和
如果窗口内元素和小于 target,那就 right++,继续将右边元素划入窗口
如果窗口内元素和大于等于target,那就更新结果,并且将左端元素划去窗口,同时判断是否满足条件并更新结果,直到小于target
话不多说上代码吧
class Solution
{
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size(), ans = INT_MAX;int sum = 0;for(int left = 0, right = 0; right < n; right++){sum += nums[right]; // 右端元素划入窗口while(sum >= target) {ans = min(ans, right - left + 1); // 满足条件更新结果sum -= nums[left];left++;}}return ans == INT_MAX ? 0 : ans; }
};
无重复字符的最长子串

思路
第一种还是暴力解法,试了一试,发现能过
思路就是每到一个位置,就遍历到无重复子串能到什么位置,找出最大长度就行
怎么判断已经到了有重复字母的位置能,我们可以用哈希表来计数,统计频次,频次大于1就截止
代码如下:
class Solution
{
public:int lengthOfLongestSubstring(string s) {int ret = 0; // 记录结果int n = s.length();// 1. 枚举从不同位置开始的最长重复子串// 枚举起始位置for (int i = 0; i < n; i++){// 创建一个哈希表,统计频次int hash[128] = { 0 };// 寻找结束为止for (int j = i; j < n; j++){hash[s[j]]++; // 统计字符出现的频次if (hash[s[j]] > 1) // 如果出现重复的break;// 如果没有重复,就更新 retret = max(ret, j - i + 1);}}// 2. 返回结果return ret;}
};
第二种解法就是滑动窗口了
想到这里是一段连续的区间,我们可以使用滑动窗口来优化
让窗口满足所有元素都不相同,右端字符不断进入窗口,然后用哈希统计频次,一旦频次有大于 1 的 就从左边划出窗口,直到这个字符频次等于1,再更新结果
如果没有大于1的频次的字符,就一直更新结果就好啦
代码如下:
class Solution
{
public:int lengthOfLongestSubstring(string s) {int hash[128] = {0}; // 使用数组模拟哈希int right = 0, left = 0, n = s.size();int ans = 0;while(right < n){hash[s[right]]++; // 进窗口while(hash[s[right]] > 1) // 维护窗口{hash[s[left++]]--;}ans = max(ans, right - left + 1);// 更新结果right++; // 下一个元素进窗口}return ans;}
};
最大连续1的个数

思路
粗看不知道怎么处理,细看想想有个k
那不就是一段连续的 1 区间塞进去 k 个 0,我们可以把问题转化成:
求一段最长的连续区间,要求这段区间内的 0 的个数不超过 k 个,连续区间问题就来到了我们的滑动窗口
流程:
right一直向右遍历,如果等于0 就进窗口,k–,每次判断 k是否小于0,如果小于 0 就处理左边left,直到 k 大于等于 0 ,同时更新结果
代码如下:
class Solution
{
public:int longestOnes(vector<int>& nums, int k) {int n = nums.size(), ans = 0;for(int left = 0, right = 0; right < n; right++){if(nums[right] == 0) // 进窗口{k--;}while(k < 0) // 判断,维护窗口 {if(nums[left] == 0){k++;}left ++ ;}ans = max(ans, right - left + 1); // 更新结果}return ans ;}
};
将x减到0的最小操作数

思路
题目要求的是 左右 两端 连续的和为x的最短数组,处理起来相对比较麻烦,我们不如反过来看,数组和为sum,sum - x就是剩下中间连续数组的和,那我们就可以把原来的问题转化成:
一段和为sum - x的最长连续子数组,又来到我们的滑动窗口啦
转化问题:求 target = sum(nums) - x 。如果 target < 0 ,问题无解
b. 初始化左右指针 l = 0 , r = 0 (滑动窗口区间表示为 [l, r) ,左右区间是否开闭很重要,必须设定与代码一致),记录当前滑动窗口内数组和的变量 sum = 0 ,记录当前满足条件数组的最大区间长度 maxLen = -1
c. 当r 小于等于数组长度时,一直循环
i. 如果 sum < target ,右移右指针,直至变量和大于等于 target ,或右指针已经移到头;
ii. 如果 sum > target ,右移左指针,直至变量和小于等于 target ,或左指针已经移到头;
iii. 如果经过前两步的左右移动使得 sum == target ,维护满足条件数组的最大长度,并让下个元素进入窗口
d. 循环结束后,如果 maxLen 的值有意义,则计算结果返回;否则,返回-1
代码如下:
class Solution
{
public:int minOperations(vector<int>& nums, int x){int sum = 0;for(int a : nums) sum += a;int target = sum - x;// 细节问题if(target < 0) return -1; // 这里就代表整个数组都小于 x int ret = -1;for(int left = 0, right = 0, tmp = 0; right < nums.size(); right++){tmp += nums[right]; // 进窗口while(tmp > target) // 维护窗口tmp -= nums[left++]; if(tmp == target) ret = max(ret, right - left + 1);// 更新结果}if(ret == -1) return ret;else return nums.size() - ret;}
};
总结
通过四个有关滑动窗口的题目,让我深有体会
主要就是抓住了核心——一段连续的区间
然后对连续的区间进行维护以及处理,滑动窗口在处理连续区间问题还是非常好用的
今天的学习就到这里啦
不要走开,小遍持续更新中~~~~~

相关文章:
coding ability 展开第三幕(滑动指针——基础篇)超详细!!!!
文章目录 前言滑动窗口长度最小的子数组思路 无重复字符的最长子串思路 最大连续1的个数思路 将x减到0的最小操作数思路 总结 前言 前面我们已经把双指针的一些习题练习的差不多啦 今天我们来学习新的算法知识——滑动窗口 让我们一起来探索滑动窗口的魅力吧 滑动窗口 滑动窗口…...
RAGFlow版本升级-Win10系统Docker
下载源码压缩包 https://github.com/infiniflow/ragflow.git 删除旧版本代码文件夹,把下载的代码解压到原先目录 更新一下env文件:ragflow/docker/.env 把值改为最新版本即可 RAGFLOW_IMAGEinfiniflow/ragflow:v0.17.1 更新一下docker docker compose -…...
通过mybatis的拦截器对SQL进行打标
1、背景 在我们开发的过程中,一般需要编写各种SQL语句,万一生产环境出现了慢查询,那么我们如何快速定位到底是程序中的那个SQL出现的问题呢? 2、解决方案 如果我们的数据访问层使用的是mybatis的话,那么我们可以通过…...
如何自己做奶茶,从此告别奶茶店
自制大白兔奶茶,奶香与茶香激情碰撞,每一口都是香浓与甜蜜的双重诱惑,好喝到跺脚!丝滑口感在舌尖舞动,仿佛味蕾在开派对。 简单几步就能复刻,成本超低,轻松在家享受奶茶自由。 材料:大白兔奶糖&…...
JavaScript性能优化实战指南
JavaScript性能优化实战指南 1. 性能分析工具与指标 核心工具链 Chrome DevTools: Performance面板:记录运行时性能,分析长任务(Long Tasks)、强制回流(Layout Shifts)、函数调用堆栈。Memory面…...
宇树人形机器人开源模型
1. 下载源码 https://github.com/unitreerobotics/unitree_ros.git2. 启动Gazebo roslaunch h1_description gazebo.launch3. 仿真效果 H1 GO2 B2 Laikago Z1 4. VMware: vmw_ioctl_command error Invalid argument 这个错误通常出现在虚拟机环境中运行需要OpenGL支持的应用…...
【Linux】浅谈冯诺依曼和进程
一、冯诺依曼体系结构 冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。 冯诺依曼的设计特点 二进制表示 所有数据(包括程序指令)均以二进制形式存储和运算,简化了硬件逻辑设计,提高了可靠性。 存储程序原理…...
env.development.local 和 env.development 的区别
env.development.local 和 env.development 的区别 区别1、场景2、git管理3、加载策略 思考原因如下 区别 1、场景 env.development: 用于开发环境的环境变量配置env.development.local: 用于存储特定于开发者的本地配置信息 2、git管理 env.development.local 会通过*.loca…...
linux操作系统实战
第一题 创建根目录结构中的所有的普通文件 [rootlocalhost ~]# cd /[rootlocalhost /]# mkdir /text[rootlocalhost /]# cd /text[rootlocalhost text]# mkdir /text/boot /text/root /text/home /text/bin /text/sbin /text/lib /text/lib64 /text/usr /text/opt /text/etc /…...
Python Cookbook-4.1 对象拷贝
任务 想拷贝某对象。不过,当你对一个对象赋值,将其作为参数传递,或者作为结果返回时,Python 通常会使用指向原对象的引用,并不是真正的拷贝。 解决方案 Python 标准库的 copy 模块提供了两个函数来创建拷贝。第一个…...
浅谈时钟启动和Systemlnit函数
时钟是STM32的关键,是整个系统的心脏,时钟如何启动,时钟源如何选择,各个参数如何设置,我们从源码来简单分析一下时钟的启动函数Systemlnit()。 Systemlnit函数简介 我们先来看一下源程序的注释…...
事业单位ABCDE类
1 我刚刚查阅了一下安徽省市直单位报名的表,我这个专业报的岗位大多数是自然科学专技岗。 2 安徽省的岗位大多都限制计算机科学与技术,我这个0854计算机技术能报的岗位十分有限。 而且我没有看到一个岗位只招应届生,显然安徽不保护应届生的…...
Python:函数(一)
python函数相关的知识点 1. 函数定义与调用 定义:使用 def 关键字,后接函数名和参数列表。 def greet(name):"""打印问候语(文档字符串)"""print(f"Hello, {name}!") 调用:…...
MySql学习_基础Sql语句
目录 1.数据库相关概念 2.SQL 2.1 SQL通用语法 2.2 SQL分类 2.3 DDL(数据库定义语言) 2.4 DML(数据操作语言) 2.5 DQL(数据查询语言) 2.6 DCL(数据控制语言) 3. 函数 3.1 字…...
Nginx 生产环境安全配置加固
以下是Nginx生产环境安全配置加固的综合方案,结合多个技术实践和行业标准整理: 一、基础安全防护 1. 隐藏版本信息 在http或server块添加server_tokens off;,避免暴露Nginx版本号。使用headers-more-nginx-module模块彻底移除响应头…...
C#中继承的核心定义
1. 继承的核心定义 继承 是面向对象编程(OOP)的核心特性之一,允许一个类(称为子类/派生类)基于另一个类(称为父类/基类)构建,自动获得父类的成员(字段、属…...
小白学Agent技术[5](Agent框架)
文章目录 Agent框架Single Agent框架BabyAGIAutoGPTHuggingGPTHuggingGPT工作原理说明GPT-EngineerAppAgentOS-Copilot Multi-Agent框架斯坦福虚拟小镇TaskWeaverMetaGPT微软UFOAgentScope现状 常见Agent项目比较概述技术规格和能力实际应用案例开发体验比较ChatChain模式 Agen…...
21.dirsearch:Web 路径扫描工具
一、项目介绍 dirsearch 是一款高效、多线程的 Web 路径扫描工具,专为渗透测试人员和网络安全研究人员设计,用于发现目标网站的隐藏目录、敏感文件及未授权接口。其支持自定义字典、代理配置、请求头伪装等功能,适用于红队渗透、漏洞挖掘及资…...
VSTO(C#)Excel开发4:打印设置
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
设计模式Python版 模板方法模式(上)
文章目录 前言一、模板方法模式二、模板方法模式示例 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式:关注类和对象之间…...
源IP泄露后如何涅槃重生?高可用架构与自动化防御体系设计
一、架构层解决方案 1. 高防代理架构设计 推荐架构: 用户 → CDN(缓存静态资源) → 高防IP(流量清洗) → 源站集群(真实IP隐藏) ↑ Web应用防火墙(WAF) 实施要点&a…...
transformer bert 多头自注意力
输入的(a1,a2,a3,a4)是最终嵌入,是一个(512,768)的矩阵;而a1是一个token,尺寸是768 a1通过wq权重矩阵,经过全连接变换得到查询向量q1;a2通过Wk权重矩阵得到键向量k2;q和k点乘就是值…...
python-leetcode-定长子串中元音的最大数目
1456. 定长子串中元音的最大数目 - 力扣(LeetCode) 可以使用 滑动窗口 方法来解决这个问题。步骤如下: 初始化:计算前 k 个字符中元音字母的个数,作为初始窗口的值。滑动窗口:遍历字符串,每次右…...
Spring Boot + MyBatis-Plus 项目目录结构
以下是一个标准的 Spring Boot MyBatis-Plus 项目目录结构及文件命名规范,包含每个目录和文件的作用说明,适用于中大型项目开发: 项目根目录结构 src/ ├── main/ │ ├── java/ # Java 源代码 │ │ └── com/…...
Python之变量及简单的数据类型
本文来源于《Python从入门到实践》,自己整理以供工作参考 基本内容 print("Hello Python World!")message "Hello Python world!" print(message)message "Helllo Python Crash Course world!" print(message)name "ada lov…...
力扣 Hot 100 刷题记录 - 翻转二叉树
力扣 Hot 100 刷题记录 - 翻转二叉树 题目描述 翻转二叉树 是力扣 Hot 100 中的一道经典题目,题目要求如下: 给你一棵二叉树的根节点 root,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7…...
力扣215.数组中的第K个最大元素--堆排序法(java)
为了找到数组中第K个最大的元素,我们可以使用堆排序的方法。堆排序的核心是构建一个最大堆,并通过多次交换堆顶元素来找到前K个最大的元素。具体步骤如下: 方法思路 构建最大堆:将输入数组转换为最大堆,使得每个父节…...
MySQL增删改查操作 -- CRUD
个人主页:顾漂亮 目录 1.CRUD简介 2.Create新增 使用示例: 注意点: 3.Retrieve检索 使用示例: 注意点: 4.where条件查询 前置知识:-- 运算符 比较运算符 使用示例: 注意点…...
【算法day9】回文数-给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文&#…...
RSA混合加密RSA混合加密
RSA混合加密是一种结合非对称加密(RSA)和对称加密(AES)的技术,通过两者的优势互补,实现高效且安全的数据传输。以下是详细解释和示例: RSA混合加密的核心原理 非对称加密(RSA&#x…...
