双指针算法——滑动窗口

前言:

滑动窗口本质上也是利用双指针来解决特定情况下的问题。滑动窗口算法思想是通过俩个指针,定义在左边和右边,俩指针同向运动,保持着一个像“窗口”一样的双指针来不停的压缩或者扩展来移动“窗口”,从而找到特定的子数组。

滑动窗口基本做题思路:

首先我们可以利用暴力解法来看看优化,是否是利用双指针来解决?双指针是否同向移动?

如果满足,可以定义为使用滑动窗口来解决,时间复杂度可以大大优化(一般为0(N))

进窗口(right指针进入,相当于扩展窗口大小,框住子数组)

判断(判断题目给定条件是否成立,要是不符合该指定条件,则left指针选择移动)

出窗口(left指针移动,相当于缩小窗口大小,直到满足题目要求即可)

更新结果(更新题目所求,得出最优结果)

一、长度最小的子数组(. - 力扣(LeetCode))

如图所述,题目要求找出一连串的子数组,其数据之和要大于等于所给定的target,而且该子数组长度是最小的,以示例一举例:

算法思路:

我们可以利用双指针来不断寻找,定义在一个“窗口”里面来找他们元素之和是否大于等于给定条件的数,先“进窗口”,right指针不断插入,遍历一遍数组,然后再判定子数组里面的元素之和是否大于等于target,若是符合,则进入“出窗口”阶段,更新最小长度,将left、继续右移,判断是否符合;若是不符合,则继续由right扩展窗口:

代码实现:

二、最大连续1的个数 (. - 力扣(LeetCode))

如图所述,给定一个数组和目标数k,题目要求是最多翻转k个0,也就是说只要不超过k次,翻转多少都可以。

相当于就是在数组中把为0的数翻转成1,最多翻转k次,然后再择出最长的连续的1的子数组,并且返回该长度。

算法思路:

首先通过暴力解法可知道双指针是同向移动,从中得知可以使用滑动窗口算法,先定义一个左右指针,然后为了不改变原数组的任何数据,我们可以使用一个计数器来统计“窗口”里面的0个数:

代码实现:

三、将x减到0的最小操作数(. - 力扣(LeetCode))

如图所述,题目要求是每一次除去左端或右端数,除去的数相加若刚好为0,则返回除去的元素数量,若无法减为0,这返回-1。

算法思路:

对于该题,常规思路不好解,代码也会很复杂。我们可以逆向思维来解题:题目告知我们需要除去左端或右端元素来解决问题,但是我们可以从中间那一段来使用滑动窗口算法解决问题:

逆向思维想好思路后利用暴力解法,我们可以再次转化为我们熟悉的滑动窗口,只需从中间选出nums_sum - (a+b) 的元素之和即可,利用“窗口”来框住子数组,剩下的就是题目所需要的最终答案了,找出目标数可以参考第一题,基本逻辑是一样的:

代码实现:

四、找到字符串中所有字母异位词(. - 力扣(LeetCode))

如图所述,题目要求是返回p中的所有异位词,异位词的定义为:

这些都称为异位词,只需要将字符串中连续的子串异位词的开始索引记录返回即可

算法思路:

依旧是使用滑动窗口来解决,但是该题毕竟不是数组,也不能使用相加的方式来做。我们可以使用哈希表来完成该题。将p中的各个字符放入哈希表中记录下来,再定义一个用于统计s中符合的子串的哈希表,最终判断俩哈希表是否相同来返回起始索引:

代码实现:

注:由于题目要求只有26个字母,所以我们可以使用数组来代替哈希表,节省时间空间复杂度

public List<Integer> findAnagrams(String s, String p) {

        List<Integer> list = new ArrayList<>();

        int[] hash1 = new int[26];//让普通数组代替hash表,26个字母

        int[] hash2 = new int[26];

        int p_len = p.length();

        int len = 0;

        for (int i = 0; i < p_len; i++) hash1[p.charAt(i) - 97]++;//创建hash1表

        for (int left=0,right=0; right < s.length();right++){

            hash2[s.charAt(right) - 97] += 1;

            len++;//进窗口

            if(len > p_len){//判断

               hash2[s.charAt(left)-97]--;

               left++;//出窗口

               len--;

            }

            if(this.My_equals(hash1,hash2)) list.add(left);//更新结果

        }

        return list;

    }

    public  boolean My_equals(int[] hash1,int[] hash2) {

        for (int i = 0; i < hash2.length; i++)

            if (hash1[i] != hash2[i])

                return false;

        return true;

    }

五、最小覆盖子串(. - 力扣(LeetCode))

如图所述,只需要包含t中所有的字符内容都可以,不论包含几个,只需要大于等于t中的字符即可,最终返回最小的子串。

算法思路:

该题与上题类似,但也有不同。区别是上题只需要统计个数即可,但此题是只论种类,不论数目.

我们依旧是用到哈希表这个容器来帮助我们完成该题。为了防止像上题一样循环26次才得出俩哈希表是否相同,我们可以使用一个小小的优化来进行改造:

然后就可以使用我们的滑动窗口来解决该问题了:

代码实现:

public String minWindow(String s, String t) {

        int[] hash1 = new int[128];//hash来代替哈希表(26+26个字母)

        int[] hash2 = new int[128];

        char in = 0, out = 0;//用来统计出入窗口时的字符

        int hash1_size = 0, len = Integer.MAX_VALUE, flg = 0;//用于统计t的种类,和最短长度,起始位置

        for (char x : t.toCharArray()) {

            hash1[x] += 1;

            if (hash1[x] == 1) hash1_size++;//只有新种类进来时才加1

        }

        for (int left = 0, right = 0, count = 0/*维护hash2的种类*/; right < s.length(); right++) {

            in = s.charAt(right);

            hash2[in]++;//进窗口

            if (hash1[in] == hash2[in]) count++;//只有相等时才加1,防止重复种类的相加

            while (count == hash1_size) {//判断

                out = s.charAt(left);

                if (len > right - left + 1) {

                    len = right - left + 1;//更新长度

                    flg = left;//更新起始位置

                }

                if (hash1[out] == hash2[out]) count--;

                hash2[out]--;

                left++;//出窗口

            }

        }

        if(len == Integer.MAX_VALUE) return "";

        else return s.substring(flg,flg + len);

    }

以上就是关于滑动窗口的经典例题,希望对大家有所帮助,谢谢各位观看!

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

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

相关文章

DigitalOcean Droplet 云主机新增内置第五代 Xeon CPU 机型

DigitalOcean 近期宣布&#xff0c;在其高级 CPU 服务器&#xff08;Premium CPU-Optimized Droplet&#xff09;队列中引入英特尔第五代Xeon可扩展处理器&#xff08;代号为 Emerald Rapids&#xff09;。作为英特尔产品线中的最新一代用于数据中心工作负载的处理器&#xff0…

LangCell:用于细胞注释的语言-细胞预训练模型

细胞身份包括细胞的各种语义&#xff0c;包括细胞类型、pathway信息、疾病信息等。从转录组数据中了解细胞身份&#xff0c;例如注释细胞类型&#xff0c;是一项基础任务。由于语义是由人类赋予的&#xff0c;如果没有cell-label pair提供监督信号&#xff0c;AI模型很难有效地…

小项目——MySQL集训(学生成绩录入)

ddl语句 -- 创建学生信息表 CREATE TABLE students (student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 学生ID,name VARCHAR(50) NOT NULL COMMENT 学生姓名,gender ENUM(男, 女) NOT NULL COMMENT 性别,class VARCHAR(50) NOT NULL COMMENT 班级,registration_date DATE CO…

Redis实战—基于setnx的分布式锁与Redisson

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P56 - P63 目录 分布式锁介绍 基于SETNX的分布式锁 SETNX锁代码实现 修改业务代码 SETNX锁误删问题 SETNX锁原子性问题 Lua脚本 编写脚本 代码优化 总结 Redisson 前言…

基于STM32的温湿度检测TFT屏幕proteus恒温控制仿真系统

一、引言 本文介绍了一个基于STM32的恒温控制箱检测系统&#xff0c;该系统通过DHT11温湿度传感器采集环境中的温湿度数据&#xff0c;并利用TFT LCD屏幕进行实时显示。通过按键切换页面显示&#xff0c;通过按键切换实现恒温控制箱的恒温控制。为了验证系统的可靠性和稳定性&…

png格式快速压缩该怎么做?在电脑压缩png图片的方法

png格式的图片如何快速压缩变小呢&#xff1f;现在网络的不断发展&#xff0c;图片是日常用来分享展示内容的一种常用手段&#xff0c;其中使用最多的一种图片格式就是png&#xff0c;png格式具有无损压缩支持透明底的特性&#xff0c;在很多的场景下都会使用。 现在图片的清晰…

Arduino - 线性执行器(支撑或滑杆)

Arduino - 线性执行器(支撑或滑杆) Arduino - 执行器 In this tutorial, we are going to learn: 在本教程中&#xff0c;我们将学习&#xff1a; How linear actuator works 线性执行器的工作原理How to make linear actuator extend or retract. 如何使线性执行器伸展或缩…

百元蓝牙耳机哪款性价比高?盘点性价比高的百元蓝牙耳机品牌

在如今快节奏的生活中&#xff0c;蓝牙耳机已经成为人们日常生活中不可或缺的配件。然而&#xff0c;市面上百元左右性价比高的蓝牙耳机琳琅满目&#xff0c;消费者往往难以选择到一款质量好、耐用的产品。我们希望可以为广大消费者提供一些参考和建议&#xff0c;接下来&#…

基于51单片机电子称—串口显示

基于51单片机电子称设计 &#xff08;仿真&#xff0b;程序&#xff09; 功能介绍 具体功能&#xff1a; 1.矩阵键盘组成按键&#xff0c;输入价格结算、打印&#xff1b; 2.用滑动变阻器和ADC0832模拟称重&#xff1b; 3.LCD1602可以显示重量、单价和总价&#xff1b; 4.…

家用洗地机十大品牌什么牌子好用?2024十大爆款洗地机分享

在快节奏的生活中&#xff0c;清洁家居成为了一项繁琐却必不可少的任务。而洗地机的出现&#xff0c;无疑给忙碌的都市人带来了福音。选择一款优质的洗地机可以大大提升我们清洁的效率&#xff0c;改善我们的生活品质。那么&#xff0c;哪家洗地机清洁力最强&#xff0c;更适合…

ONLYOFFICE 桌面编辑器 8.1 版发布:全面提升文档处理效率的新体验

文章目录 什么是ONLYOFFICE &#xff1f;ONLYOFFICE 桌面编辑器 8.1 发布&#xff1a;新功能和改进功能强大的 PDF 编辑器幻灯片版式功能从右至左语言支持多媒体功能增强无缝切换工作模式其他改进和优化总结 什么是ONLYOFFICE &#xff1f; https://www.onlyoffice.com/zh/off…

JavaScript的学习之图片的切换

目录 一、寻找素材 二、编写简单的静态html页面 代码示例 效果展示 三、JS功能的实现 JS代码 完整代码 效果展示 一、寻找素材 随便去网上找几张图片素材 二、编写简单的静态html页面 代码示例 <!doctype html> <html><head><meta charset"…

svn明明都在环境变量中添加了,但还是无法在cmd中生效

svn明明都在环境变量中添加了&#xff0c;但还是无法在cmd中生效 cmd显示原因问题解决 cmd显示 svn不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件 原因 安装svn一直点下一步下一步…&#xff0c;没有勾选command line client。 问题解决 1.按下winx&…

如何加密电脑文件?电脑重要文件怎么加密?

在电脑中&#xff0c;我们会存储很多重要文件&#xff0c;包括个人隐私视频、照片&#xff0c;企业机密数据&#xff0c;工作数据等。为了避免重要文件泄露&#xff0c;我们需要加密保护电脑文件。下面我们就来了解一下电脑文件怎么加密&#xff1f; 超级加密3000 当需要加密电…

vue 实现 word/excel/ppt/pdf 等文件格式预览操作

效果图&#xff1a; 问题描述&#xff1a;一般情况下使用iframe标签就可以实现文件预览&#xff0c;但是这个标签只针对于ppt和pdf是有效的。对于doc文件就需要借助第三方插件&#xff08;vue-office/docx&#xff09;来实现预览了。下面介绍使用方法。 安装插件&#xff1a;n…

力扣爆刷第155天之TOP100五连刷41-45(下一个排列、正序数组中位数、归并排序链表)

力扣爆刷第155天之TOP100五连刷41-45&#xff08;下一个排列、正序数组中位数、归并排序链表&#xff09; 文章目录 力扣爆刷第155天之TOP100五连刷41-45&#xff08;下一个排列、正序数组中位数、归并排序链表&#xff09;一、31. 下一个排列二、4. 寻找两个正序数组的中位数三…

量化交易策略:定义及其重要性

量化交易是华尔街和硅谷的秘密结合点&#xff0c;在这里数学和算法与金钱和市场相遇。虽然它曾经是金融巨头的专属领域&#xff0c;但现在它比以往任何时候都更易于接触。 但不要被愚弄&#xff0c;量化交易仍然是一种高速、高压的游戏&#xff0c;在毫秒间可以赚到或失去财富…

STM32CubeIDE复制工程文档

目录 1. 粘贴复制2. 重命名 1. 粘贴复制 复制粘贴 重命名&#xff0c;别重名&#xff0c;点击- copy 结果 2. 重命名 重命名 ioc文件 编译 OK

IDEA 安装与激活详细教程最新(附最新激活码)2099年亲测有效!

我们先从 IDEA 官网下载 IDEA 2024.1 版本的安装包&#xff0c;下载链接如下&#xff1a; https://www.jetbrains.com/idea/download/ 点击下载(下载Ultimate版)&#xff0c;静心等待其下载完毕即可。 激活方式&#xff1a; 正版专属激活码领取

手机越用越慢?试试这4个秘籍,让手机流畅如新

智能手机作为日常生活的得力助手&#xff0c;最初总是以惊人的速度和流畅性给我们留下深刻印象。 但你有没有发现&#xff0c;随着时间的推移&#xff0c;手机似乎开始变得不那么敏捷&#xff0c;甚至出现了反应迟缓和卡顿的情况&#xff1f; 别让这个问题困扰你,下面是四个关…