我爱学算法之——滑动窗口攻克子数组和子串难题(上)

现在来学习"滑动窗口"这一算法思想。

至于什么是"滑动窗口"呢?简单来说就是同向双指针;现在来通过题目来了解什么是"滑动窗口"

一、长度最小的子数组

题目链接:长度最小的子数组

题目解析

在这里插入图片描述

先来看题目,给了一个数组nums和一个整数target,让我们找到nums的一个满足条件(条件:子数组的和大于target)的最长子数组。

算法思路

首先第一次看到子数组/子串问题的算法题,能想到的思路就肯定是暴力枚举了;现在就先来看暴力枚举如何解决的。

暴力枚举

我们依次枚举整个数组的每一个子数组,并判断是否满足条件;满足条件且长度小于最总结果,就更新最终结果。

上面意思呢?

在这里插入图片描述

暴力解法的大致思路如上述所示;现在来看一下暴力枚举有哪些操作是不必要的

  • right第一次找到满足条件的位置并更新结果后,left++rightleft位置再重新遍历

这个操作感觉有些多余了,因为我们right遍历时第一次遇到满足条件的就停了下来;

如果rightleft++后的位置开始再遍历到上次满足条件位置的位置,这一个遍历过程很多余;

什么意思呢?

就以暴力枚举中的示例来说:

right第一次遍历到下标为3位置恰好满足条件;此时区间是[0,3],我们更新结果之后,left++

right从下标为1的位置开始再次遍历;

我们直到[0,3]区间刚满足条件,那区间[1,1][1,2]是一定不满足条件的[1,3]才有可能满足条件。

那这样我们就可以想办法省略这个不必要的步骤:

找到满足条件的区间,并更新结果并lef++后,如何去解决right重新遍历的问题?

解决问题,我们要找到问题的本质

**暴力枚举**中为什么要重新进行遍历,本质问题就是我们不知道left++后,区间[left,right]的和;(所以暴力枚举才会进行重新遍历)

那我们现在定义一个变量sum来实时记录区间[left,right]的和,这样不就不需要重新遍历了吗。

我们只需要在right向后遍历和left更新时,顺手更新一下sum的值就可以了。

滑动窗口

其实滑动窗口就是优化了暴力枚举解法中不必要的部分

知道了如何去解决暴力枚举中不必要的问题,现在来实现

在这里插入图片描述

通过上图所示推到,我们的想法是可行的,现在来看整体的一个思路

滑动窗口,为什么称为滑动窗口?

就是rightleft在遍历更新的过程中维护了一段区间[left , right],这个区间像窗口一样在数组中滑动。

现在来看实现这个问题的一个整体思路:

  • 进窗口:让right向右遍历,更新区间[left , right]的和sum;称为进窗口(就是让right遍历到的元素进入(窗口)区间内。
  • 出窗口:如果当前区间满足条件(区间大于target),就更新结果,然后让left++,并更新区间[left , right]的和;重复上述操作直到区间不满足条件。
  • 更新结果:至于什么时候更新结果,每一道题都不一样,根据题目中的要求再决定什么时候更新结果。

代码实现

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size();int ret = n+1;int l=0,r=0;int sum =0;while(l<n){//进窗口sum += nums[l++];//出窗口while(sum>=target){int x= l-r;if(x < ret)ret = x;sum-=nums[r++];}}if(ret == n+1)return 0;return ret;}
};

二、无重复字符的最长子串

题目链接:无重复字符的最长子串

题目解析

在这里插入图片描述

题目要求找出来给定字符串的所有子串中,不包含重复字符的最长子串;(也是子串问题)

  • s字符串中的字符由英文字母、数字、符号和空格组成。

算法思路

这里首先还是来看暴力解法

枚举出来所有不包含重复字符的子串

在其中找到最长的然后返回。

这里先来看一下如何处理重复字符的问题:

这里可以使用一个hash表,其中记录每一个字符出现的次数;

这样使用leftright双指针遍历的时候,遍历到hash[s[right]] > 1就代表当前区间内存在重复字符。

当然这里所有数组来模拟hash就可以了

现在来看使用滑动窗口如何去解决。

进窗口:首先right向右遍历,遍历过程中hash[s[right]]++更新当前字符出现的次数;

出窗口:当hash[s[right]] >1时就表示当前区间不满足条件,就要left++并且hash[s[left]]--更新区间内字符出现的字符;直到hash[s[right]]<=1

更新结果:这里每一次出完窗口就表示找到了一个满足条件的区间,所以出完窗口之后更新结果即可。(这里在right刚开始遍历,每一次出完窗口,不一定会进入出窗口,但是也会更新结果,不会遗漏)。

代码实现

这里写代码时注意,我们数组模拟hash,数组大概开辟128就差不多够了。

class Solution {
public:int lengthOfLongestSubstring(string s) {int hash[128]={0};int n = s.size();int left = 0, right = 0;int ret = 0;while(right < n){//进窗口hash[s[right]]++;while(hash[s[right]]>1)hash[s[left++]]--;ret = max(ret,right-left+1);right++;}return ret;}
};

三、最大连续1的个数 III

题目链接:最大连续1的个数 III

题目解析

在这里插入图片描述

题目给定一个数组nums,和k;其中nums中每一个数字不是1就是0

k表示最多可以反转(01)的次数。

要求我们返回操作之后,数组中连续1的最大个数。

什么意思呢?

就是我们最多可以将k个数组中的0变成1,然后我们要找出进行变换操作后数组中连续1的最大个数。

算法思路

这里,做出来本道题的关键就在于如何处理这个最多k01的问题。

这里我们真的要将0变成1?

显然是不可以的,这里数组有很多子数组,变了之后如何接着进行呢?

所以我们不能这样操作,就只能另辟蹊径:

这道题也是最长子数组问题,那也是要用滑动窗口的;我们想一想如何将其变成这样的问题?

很显然,这里题目要求最多可以进行k次变换,我们不能进行真的变化操作。

就只能在原数组中找到一个子数组(其中0的个数不超过k);

这样这个问题就变成了我们熟悉的找子数组的问题,这里条件就是区间内0的个数不超过k

所以思路就简单明了了。

这里定义一个变量zero来记录区间[left , right]0的个数。

入窗口:right向右遍历,遇到0就更新zero

出窗口:如果zero>k就表示当前区间内不满足条件了,就进行出窗口操作;如果nums[left] == 0,就更新zero

更新结果:这里更新结果还是在出窗口之后,出窗口之后区间是满足条件的并且每次入窗口之后不一定会出窗口,这样更新就不会漏掉每一种情况。

代码实现

class Solution {
public:int longestOnes(vector<int>& nums, int k) {int n = nums.size();int left = 0, right =0;int zero = 0;int ret = 0;while(right<n){//入窗口if(nums[right++] == 0)zero++;//出窗口while(zero>k){if(nums[left++]==0)zero--;}//更新结果ret = max(ret,right - left);}return ret;}
};

这里第一次接触到滑动窗口,感觉有一点点抽象;

这里滑动窗口其实就是同向双指针,只是在遍历的过程中维护了一段区间就像一个窗口一样在数组中滑动。

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

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

相关文章

ora-600 ktugct: corruption detected---惜分飞

接手一个oracle 21c的库恢复请求,通过Oracle数据库异常恢复检查脚本(Oracle Database Recovery Check)脚本检测之后,发现undo文件offline之后,做了resetlogs操作,导致该文件目前处于WRONG RESETLOGS状态 尝试恢复数据库ORA-16433错误 SQL> recover datafile 1; ORA-00283:…

20. Excel 自动化:Excel 对象模型

一 Excel 对象模型是什么 Excel对象模型是Excel图形用户界面的层次结构表示&#xff0c;它允许开发者通过编程来操作Excel的各种组件&#xff0c;如工作簿、工作表、单元格等。 xlwings 是一个Python库&#xff0c;它允许Python脚本与Excel进行交互。与一些其他Python库&#x…

IIS 服务器日志和性能监控

Internet Information Services &#xff08;IIS&#xff09; 是 Microsoft 提供的一款功能强大、灵活且可扩展的 Web 服务器&#xff0c;用于托管网站、服务和应用程序。IIS 支持 HTTP、HTTPS、FTP、SMTP 和更多用于提供网页的协议&#xff0c;因此广泛用于企业环境。 IIS 的…

jenkins pipline 自动化测试

以下是一个典型的 Jenkins Pipeline 示例&#xff0c;用于执行自动化测试流程&#xff08;支持单元测试、集成测试、代码质量扫描&#xff09;&#xff0c;包含多阶段执行和测试结果处理&#xff1a; pipeline {agent anyenvironment {// 定义环境变量PROJECT_NAME "my-…

APP测试

一、APP测试范围 功能测试性能测试&#xff1a;CPU、内存占用、启动速度、流量、电量消耗、流畅度、稳定性专项测试&#xff1a;安装卸载升级、push消息推送 、交叉事件测试 、用户体验测试 、兼容性测试 二、APP包发布方式及策略 分类&#xff1a; 内部发布渠道。如&#x…

12 File文件对象:创建、获取基本信息、遍历文件夹、查找文件;字符集的编解码 (黑马Java视频笔记)

文章目录 File >> 存储数据的方案1. 认识File2. File操作2.1 创建File对象2.2 File操作1&#xff09;对文件对象的信息的操作2&#xff09;文件/文件夹的创建/删除3&#xff09;⭐⭐对文件夹的遍历 3. 方法递归3.1 认识递归3.2 递归算法及其执行流程1) 案例&#xff1a;2…

oracle 基础知识之 多表查询

多表查询定义&#xff1a;当查询的数据并不是来源一个表时&#xff0c;需要使用多表连接操作完成查询。多表连接查询通过表之间的关联字段&#xff0c;一次查询出多个表的数据。多表查询包括了等值连接、左连接、右连接、完全连接。 1.等值连接 等值连接也称为简单连接&#xf…

服务器防火墙根据什么特征来过滤数据包?

防火墙是服务器安全防护的第一道屏障&#xff0c;它的主要作用是监控、过滤和控制进出服务器的数据流量&#xff0c;防止恶意攻击、非法访问和数据泄露。防火墙通过分析数据包的特定特征来决定是否允许、拒绝或限制数据的传输。 服务器防火墙的基本工作原理&#xff1a; 防火墙…

Prims region.Views 为null

原因&#xff1a; 导航未完成或异步问题 解决方式&#xff1a;使用回调确认导航完成后再操作视图 _regionManager.RequestNavigate("MonitorRegion", "MonitorView", nps, navigationResult > {if (navigationResult.Result true){var region _regio…

reconstruct_3d_object_model_for_matching例子

文章目录 1.获取om3文件2.准备可视化3.准备3D可视化4.读取3D模型5.显示成对注册结果16.显示成对注册结果27.联合注册模型8.处理图像8.1子采样8.2 图像计算与平滑8.3 三角测量 9.基于表面做3D匹配10.评估模型准确度10.1 在场景中找到模型10.2 计算模型和场景之间的距离 11.立体系…

软件安全性测试的重要性和常用工具介绍,软件测试服务公司推荐

在当今数字化快速发展的时代&#xff0c;软件已经成为各行各业不可或缺的一部分。然而&#xff0c;随着软件系统的复杂性增加&#xff0c;安全性问题也愈发突出&#xff0c;因此软件产品生产周期中安全测试必不可少。软件安全性测试是指对软件系统进行评估&#xff0c;以发现潜…

Redis项目:短信验证码登录

这是黑马的黑马点评项目&#xff0c;短信验证码的业务。一开始是使用session做的&#xff0c;后来重构&#xff0c;使用redis缓存来完成。 第一层拦截器&#xff1a; public class RefreshTokenInterceptor implements HandlerInterceptor {private StringRedisTemplate stri…

Docker下载,包含Win、Mac

介绍 Docker 是一种开源的容器化平台&#xff0c;通过操作系统级虚拟化技术实现应用的快速开发、部署和运行。以下从多个维度对 Docker 进行详细介绍&#xff1a; 一、Docker 的核心概念与功能 容器化技术 Docker 利用 Linux 内核的容器隔离技术&#xff08;如 Cgroups 和 Nam…

使用 ESP8266 和 Android 应用程序实现基于 IOT 的语音控制家庭自动化

使用 ESP8266 实现基于 IOT 的语音控制家庭自动化 欢迎来到另一个令人兴奋的项目,我们将使用 Wi-Fi 模块构建一个语音控制ESP8266家庭自动化系统,您可以在其中通过语音通过 Android 应用程序从世界任何地方控制您的家用电器。是的,您只需使用语音命令即可打开或关闭负载(L…

【HarmonyOS Next】鸿蒙中自定义弹框OpenCustomDialog、CustomDialog与DialogHub的区别详解

【HarmonyOS Next】鸿蒙中自定义弹框OpenCustomDialog、CustomDialog与DialogHub的区别详解 一、三者的区别与关系 1. 官方迭代过程为&#xff1a; CustomDialog 》 OpenCustomDialog 》 DialogHub 迭代过程表明&#xff0c;弹框的调用越来越便捷&#xff0c;与UI解耦&…

【C++】stack和queue的使用及模拟实现(含deque的简单介绍)

文章目录 前言一、deque的简单介绍1.引入deque的初衷2.deque的结构3.为什么选择deque作为stack和queue的底层默认容器 二、stack1.stack的介绍2.stack的使用3.stack的模拟实现 三、queue1.queue的介绍2.queue的使用3.queue的模拟实现 前言 一、deque的简单介绍&#xff08;引入…

Leetcode 刷题笔记1 图论part01

图论的基础知识&#xff1a; 图的种类&#xff1a; 有向图&#xff08;边有方向&#xff09; 、 无向图&#xff08;边无方向&#xff09;、加权有向图&#xff08;边有方向和权值&#xff09; 度&#xff1a; 无向图中几条边连接该节点&#xff0c;该节点就有几度&#xff1…

《基于Workspace.java的Launcher3改造:HotSeat区域动态阻断文件夹生成机制》

1. 需求背景与技术挑战 在Android 13系统Launcher3定制化开发中&#xff0c;需实现禁止HotSeat区域创建文件夹的功能。原始逻辑中&#xff0c;当用户拖拽应用图标至HotSeat区域相邻图标时&#xff0c;会触发FolderIcon的实例化。本文将深入分析Launcher3的文件夹创建机制&…

重生之我在学Vue--第14天 Vue 3 国际化(i18n)实战指南

重生之我在学Vue–第14天 Vue 3 国际化(i18n)实战指南 文章目录 重生之我在学Vue--第14天 Vue 3 国际化(i18n)实战指南前言一、Vue I18n 核心配置1.1 基础环境搭建1.2 初始化配置1.3 全局挂载 二、多语言实现方案2.1 基础使用2.2 动态切换语言2.3 高级功能实现复数处理日期/货币…

开源PACS(dcm4che-arc-light)部署教程,源码方式

目录 文件清单下载地址安装概述OpenLDAP、Apache Directory StudioWildflydcm4che 安装部署MySQL源码编译dcm4cheedcm4chee-arc-light OpenLDAP安装ApacheDirectoryStudio安装配置WildFly服务器 部署完成 文件清单 下载地址 Apache directory studio - linkOpenLDAP - linkdcm…