D2力扣滑动窗口系列

滑动窗口算法(Sliding Window)

滑动窗口算法(Sliding Window):在给定数组 / 字符串上维护一个固定长度或不定长度的窗口。可以对窗口进行滑动操作、缩放操作,以及维护最优解操作。

  • 滑动操作:窗口可按照一定方向进行移动。最常见的是向右侧移动。
  • 缩放操作:对于不定长度的窗口,可以从左侧缩小窗口长度,也可以从右侧增大窗口长度。

滑动窗口利用了双指针中的快慢指针技巧,我们可以将滑动窗口看做是快慢指针两个指针中间的区间,也可以将滑动窗口看做是快慢指针的一种特殊形式。

适用范围&题型:

滑动窗口算法一般用来解决一些查找满足一定条件的连续区间的性质(长度等)的问题。该算法可以将一部分问题中的嵌套循环转变为一个单循环,因此它可以减少时间复杂度。

按照窗口长度的固定情况,我们可以将滑动窗口题目分为以下两种:

  • 固定长度窗口:窗口大小是固定的。
  • 不定长度窗口:窗口大小是不固定的。
    • 求解最大的满足条件的窗口。
    • 求解最小的满足条件的窗口。

不定长度滑动窗口算法

不定长度滑动窗口算法(Sliding Window):在给定数组 / 字符串上维护一个不定长度的窗口。可以对窗口进行滑动操作、缩放操作,以及维护最优解操作。

算法步骤:

使用两个指针left、right。初始时,left、right都指向序列的第一个元素。即:left=right=0;
区间[left,right]被称为一个「窗口」。将区间最右侧元素添加入窗口中,即 window.add(s[right])。
然后向右移动 right++,从而增大窗口长度,直到窗口中的连续元素满足要求。此时,停止增加窗口大小。
转向不断将左侧元素移出窗口,即 window.popleft(s[left])。
然后向右移动left++,从而缩小窗口长度。直到窗口中的连续元素不再满足要求。

 时间复杂度0\left ( n \right )

例题: 

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

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

这道题目典型的求不定长度窗口的题。(字符串的子串一般使用滑动窗口)

本题解答:遍历字符串,如果字符没出现过,就放到窗口中,即right++,出现过,就把他(包含前面的)扔出窗口即left--;

关于字符串是否出现过有两种解法。

方法一:建立数组 bool hash[256],出现过就1,没有出现过就0;

class Solution {//不定滑动窗口大小
public:int lengthOfLongestSubstring(string s) {if(s.size()==0) return 0;int left=0;int right=0;//定义滑动窗口指针bool hash[256]={0};//定义字母数组,用来判断字母是否出现过,如果字母出现过为1,没出现过为0;int maxl=0;int len=0;while(right<s.size()){if(hash[s[right]]==0){//元素未出现过hash[s[right]]=1;right++;len++;}else{//出现过hash[s[left]]=0;left++;len--; }maxl=max(maxl,len);}return maxl;}
};​

方法二:使用 unordered_set()无需字符集合。

huadong.find(s[i])!=huadong.end()//s[i]存在
huadong.insert(s[i])//插入元素
huadong.erase(s[i])//删除元素
class Solution {//滑动窗口
//大题思想:遍历s中的元素,如果不在滑动窗口中重复,就加入窗口(此时,窗口长度会增大)。如果重复,就从窗口中删除元素(此时窗口长度减少,开始位置后移)。
public:int lengthOfLongestSubstring(string s) {int maxl=0;//maxl最大值;if(s.size()==0) return 0;//创建无序字符集合,保存滑动窗口unordered_set<char> huadong;int start=0;//滑动窗口的startfor(int i=0;i<s.size();i++){while(huadong.find(s[i])!=huadong.end()){//当前字符s[i]在集合 huadong中已经存在 huadong.erase(s[start]);//将其删除,滑动窗口的起始位置后移start++;}maxl=max(maxl,i-start+1);huadong.insert(s[i]);}return maxl;}
};

时间复杂度0\left ( n \right )。 

类似题目:

209. 长度最小的子数组

大体思路:

eg. nums = [2,3,1,2,4,3] 

将元素一直往窗口里面放,当sum>target时,往外扔元素。

为什么可以一直往里面放元素呢?首先一开始sum<target,肯定可以往里放,后面>的时候,进入while循环,一旦while结束,必定又<,并且这样能实现right++,从而跳出循环。

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int left=0;int right=0;int sum=0;int ans=INT_MAX;while(right<nums.size()){sum+=nums[right];while(sum>=target){ans=min(ans,right-left+1);sum-=nums[left];left++;}right++;}return ans== INT_MAX ? 0 : ans;}
};
  • 时间复杂度0\left ( n \right )空间复杂度0\left ( 1 \right )

类似题目:

  • 713. 乘积小于K的子数组 - 力扣(LeetCode)

固定长度滑动窗口算法:

固定长度滑动窗口算法(Fixed Length Sliding Window):在给定数组 / 字符串上维护一个固定长度的窗口。可以对窗口进行滑动操作、缩放操作,以及维护最优解操作。

 算法思想:

假设窗口的固定大小为 window_size。使用两个指针 left、right。
初始时,left、right 都指向序列的第一个元素,即:left、right=0
区间 [left,right]被称为一个「窗口」。当窗口未达到 window_size 大小时,不断移动right,即right++。
先将数组前 window_size个元素填入窗口中,即 window.append(nums[right])。当窗口达到 window_size 大小时,即满足 right - left + 1 >= window_size 时,
判断窗口内的连续元素是否满足题目限定的条件。如果满足,再根据要求更新最优解。然后向右移动 left,从而缩小窗口长度,即 left += 1,使得窗口大小始终保持为 window_size。向右移动 right,将元素填入窗口中,即 window.append(nums[right])。重复上述步骤,直到right 到达数组末尾

例题:

1343. 大小为 K 且平均值大于等于阈值的子数组数目

给你一个整数数组 arr 和两个整数 k 和 threshold 。

请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。

数组题目一定注意越界情况

解法一:仍然使用双指针。

这里要注意先算sum,再进行right++,否则会出现越界情况

class Solution {
public:int numOfSubarrays(vector<int>& arr, int k, int threshold) {int left=0;int right=0;int ans=0;int sum=0;//float avg;求出它们的元素和,如果这个和大于等于threshold*k,那么就说明其平均值大于等于threshold了。//这样处理可以不用涉及除法运算,避免引入浮点数,效率更高。//vector<int> window;while(right<k){//先加入k个元素// window.push_back(arr[right]);sum+=arr[right++];}if(sum>=threshold*k)//判断前k个元素的和是否满足。ans++;while(right<arr.size()){//先运算避免后面越界sum+=arr[right++]-arr[left++];//下一个k个元素和if(sum>=threshold*k)ans++;         }      return ans;}
};

int sum=0;//float avg;求出它们的元素和,如果这个和大于等于threshold*k,那么就说明其平均值大于等于threshold了。
 //这样处理可以不用涉及除法运算,避免引入浮点数,效率更高。

改进一下:其实left与 right的距离相同,可以直接不用变换left,直接用right-left+1来判断

class Solution {
public:int numOfSubarrays(vector<int>& arr, int k, int threshold) {int left=0;int right=0;int ans=0;int sum=0;//float avg;求出它们的元素和,如果这个和大于等于threshold*k,那么就说明其平均值大于等于threshold了。//这样处理可以不用涉及除法运算,避免引入浮点数,效率更高。//vector<int> window;while(right<k){// window.push_back(arr[right]);sum+=arr[right++];}while(right<arr.size()){if(sum>=threshold*k) ans++; sum += arr[right] - arr[right - k];right++;}if(sum>=threshold*k)ans++; return ans;}
};

类似题目:1052. 爱生气的书店老板

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

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

相关文章

【Ubuntu】gonme桌面的 gdm 和 lightdm 区别

总结&#xff1a;都可以 gdm: 【Gnome Display Manager】 完整&#xff0c;体积大 lightdm: 【Light Display Manager】 轻量

甜甜圈和贪吃蛇的后续

代码复现-项目复现 代码复现 云课五分钟-02第一个代码复现-终端甜甜圈C-CSDN博客 项目复现 云课五分钟-03第一个开源游戏复现-贪吃蛇-CSDN博客 不同的地图 加入班级和标识 循序渐进 这些案例都是来源网络&#xff0c;只是方便熟悉一下云课使用过程。 此部分学生掌握情况非…

OpenCV 图像的几何变换

一、图像缩放 1.API cv2.resize(src, dsize, fx0,fy0,interpolation cv2.INTER_LINEAR) 参数&#xff1a; ①src &#xff1a;输入图像 ②dsize&#xff1a;绝对尺寸 ③fx&#xff0c;fy&#xff1a;相对尺寸 ④interpolation&#xff1a;插值方法 2.代码演示 import cv2 …

携手亚信安慧AntDB,在数智化浪潮中乘风破浪

随着大数据时代的到来&#xff0c;对数据库的需求愈发强烈。在这一背景下&#xff0c;国产数据库逐渐崭露头角&#xff0c;亚信安慧AntDB作为重要的代表产品之一正积极参与到激烈的市场竞争中。亚信安慧AntDB不仅追求技术的革新和突破&#xff0c;同时也致力于满足用户日益增长…

AVCE - AV Evasion Craft Online 更新 8 种加载方式 - 过 WD 等

免责声明&#xff1a;本工具仅供安全研究和教学目的使用&#xff0c;用户须自行承担因使用该工具而引起的一切法律及相关责任。作者概不对任何法律责任承担责任&#xff0c;且保留随时中止、修改或终止本工具的权利。使用者应当遵循当地法律法规&#xff0c;并理解并同意本声明…

2023年中国高校大数据挑战赛D题参考论文发布(全网首发)

腾讯文档】2023年大数据挑战赛资料说明 https://docs.qq.com/doc/DSEpWUVFySm1ObFB0 基于数据分析的行业职业技术培训能力评价 摘要 中国是制造业大国&#xff0c;产业门类齐全&#xff0c;每年需要培养大量的技能娴熟的技术工人进入工厂。本文将基于题目给出的数据&#x…

Java——正则表达式详解

目录 Java正则表达式1、正则表达式语法1.1、基本的元字符1.2、数量元字符1.3、位置元字符1.4、特殊字符元字符1.5、回溯引用和前后查找1.6、大小写转换1.7、匹配模式 2、Java中的正则表达式2.1、概述2.2、获取匹配位置2.3、捕获组 3、匹配单个字符3.1、匹配纯文本3.2、匹配任意…

讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so

1.需求 最近linux下的Qt项目中要连接oracle数据库&#xff0c;用户需要我们访问他们的oracle数据库&#xff0c;查询数据 2.遇到的问题 qt连接oracle数据库需要oracle的驱动库libqsqloci.so插件&#xff0c;需要编译下&#xff0c;之前没有编译过&#xff0c;看了网上的…

蓝桥杯真题讲解:异或和之和 (拆位、贡献法)

蓝桥杯真题讲解&#xff1a;异或和之和 &#xff08;拆位、贡献法&#xff09; 一、视频讲解二、正解代码 一、视频讲解 蓝桥杯真题讲解&#xff1a;异或和之和 &#xff08;拆位、贡献法&#xff09; 二、正解代码 //拆位考虑 #include<bits/stdc.h> #define endl &…

【c++】string类的使用及模拟实现

1.我们为什么要学习string类&#xff1f; 1.1 c语言中的字符串 我们先了解一下什么是OOP思想 OOP思想&#xff0c;即面向对象编程&#xff08;Object-Oriented Programming&#xff09;的核心思想&#xff0c;主要包括“抽象”、“封装”、“继承”和“多态”四个方面。 抽象…

JDBC和连接池

JDBC和连接池 大纲 JDBC连接数据库的方式JDBCUtils事务 具体案例 JDBC 需求&#xff1a;满足Java程序能对多个不同的数据库进行操作&#xff0c;而创建了一种接口&#xff0c;实现对数据库的规范 连接数据库的方式 1.方法1 先创建一个Driver对象&#xff0c;然后设置…

【RabbitMQ】RabbitMQ的交换机

交换机类型 在上文中&#xff0c;都没有交换机&#xff0c;生产者直接发送消息到队列。而一旦引入交换机&#xff0c;消息发送的模式会有很大变化&#xff1a;可以看到&#xff0c;在订阅模型中&#xff0c;多了一个exchange角色&#xff0c;而且过程略有变化&#xff1a; Pub…

Android bp构建引入其他模块头文件

最近做项目过程中经常遇到Android.bp文件引入其他模块的头文件库&#xff0c;总是记不住bp的写法&#xff0c;这里做个记录 1.产生头文件库 2.其他的模块应用引入头文件库 不由想起来老师的名句&#xff1a;好记忆不如烂笔头。

基于遗传算法改进的RBF神经网络流量控制,基于GA-RBF的流量预测

目录 完整代码和数据下载链接:基于遗传算法改进的RBF神经网络流量控制,基于GA-RBF的流量预测(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88937452 RBF的详细原理 RBF的定义 RBF理论 易错及常见问题 RBF应用实例,基于遗传算法改…

【Python使用】python高级进阶知识md总结第3篇:静态Web服务器-返回指定页面数据,静态Web服务器-多任务版【附代码文档】

python高级进阶全知识知识笔记总结完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;操作系统&#xff0c;虚拟机软件&#xff0c;Ubuntu操作系统&#xff0c;Linux内核及发行版&#xff0c;查看目录命令&#xff0c;切换目录命令&#xff0c;绝对路径和相对…

笔记79:ROS入门之前的准备

一、ROS是什么 ROS其实是一个伪操作系统&#xff0c;是基于Liunx操作系统的一个用于机器人各个节点之间通信的系统&#xff1b;ROS制定了一系列规则使得每个节点之间遵循相同的通信规则&#xff0c;使得每个人都可以有一个守则区遵守开发自己的节点&#xff0c;也能和别人开发…

Linux -- 线程概念和控制

一 什么是线程 1.1 线程的引出 我们开始理解一下Linux中的线程。我们以前说过&#xff0c;一个进程被创建出来&#xff0c;要有自己对应的进程PCB的&#xff0c;也就是 task_struct&#xff0c;也要有自己的地址空间、页表&#xff0c;经过页表映射到物理内存中。所以在进程角…

基于java ssm springboot女士电商平台系统

基于java ssm springboot女士电商平台系统源码文档设计 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末…

WebPack自动吐出脚本

window.c c; window.res ""; window.flag false;c function (r) {if (flag) {window.res window.res "${r.toString()}" ":" (e[r] "") ",";}return window.c(r); }代码改进了一下&#xff0c;可以过滤掉重复的方…

web基础05-jQuery

目录 一、jQuery 1.概述 2.原生js与jQuery对比 3.特点 4.使用 &#xff08;1&#xff09;入口函数 &#xff08;2&#xff09;语法 &#xff08;3&#xff09;jQuery选择器 5.方法 &#xff08;1&#xff09;获取属性值&#xff1a; &#xff08;2&#xff09;删除属…