当前位置: 首页 > news >正文

[算法] 优先算法(三):滑动窗口(上)

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀Java EE(94平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
在这里插入图片描述

目录

  • 1. 概述
  • 2. 长度最小的子数组(难度:🔵2度)
  • 3. 无重复字符的最长子串(难度:🔵2度)
  • 4. 最大连续1的个数III(难度:🟡3度)
  • 5. 将x减到0的最小操作数(难度:🟡3度)

1. 概述

所谓滑动窗口,也叫通向双指针,就是在我们上一个板块双指针的基础上,把双指针的"点"变换成"线",双指针表示两个点,而滑动窗口则是由双指针的两个"点"构成"线",表示一个区间.
滑动窗口最基本有以下几步的操作:

  1. 指定left=0right=0两个左右指针.
  2. 让右指针右移,进入窗口.
  3. 让左指针右移,出窗口.
  4. 更新结果,结果在哪一步更新不确定,需要具体问题具体分析.

2. 长度最小的子数组(难度:🔵2度)

OJ链接

  • 题目描述

给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续
子数组
[numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

  • 算法原理
    由于此问题分析的对象是「⼀段连续的区间」,因此可以考虑「滑动窗⼝」的思想来解决这道题。
    让滑动窗⼝满⾜:从i 位置开始,窗⼝内所有元素的和⼩于target (那么当窗⼝内元素之和
    第⼀次⼤于等于⽬标值的时候,就是i 位置开始,满⾜条件的最⼩⻓度
    )。
    做法:将右端元素划⼊窗⼝中,统计出此时窗⼝内元素的和:
    • 如果窗⼝内元素之和⼤于等于target :更新结果,并且将左端元素划出去的同时继续判
      断是否满⾜条件并更新结果
      (因为左端元素可能很⼩,划出去之后依旧满⾜条件)
    • 如果窗⼝内元素之和不满⾜条件: right++ ,另下⼀个元素进⼊窗⼝。
  • 为什么滑动窗口可以保证最终结果的正确性,而且时间复杂度很低?
    • 这个窗⼝寻找的是:以当前窗口最左侧元素(记为left1 )为基准,符合条件的情况。也
      就是在这道题中,从left1 开始,满⾜区间和sum >= target 时的最右侧(记为right1 )能到哪⾥。
    • 我们既然已经找到从left1 开始的最优的区间,那么就可以大胆舍去left1 。但是如
      果使用暴力解法,重新开始统计第⼆个元素( left2 )往后的和,势必会有⼤量重复
      的计算(因为我们在求第⼀段区间的时候,已经算出很多元素的和了,这些和是可以在计算
      下次区间和的时候用上的
      )。
    • 此时, rigth1 的作⽤就体现出来了,我们只需将left1 这个值从sum 中剔除
      right1 这个元素开始,往后找满足left2 元素的区间
      (此时right1 也有可能是满
      ⾜的,因为left1 可能很⼩。 sum 剔除掉left1 之后,依旧满⾜⼤于等于
      target )。这样我们就能省掉⼤量重复的计算。
    • 这样我们不仅能解决问题,⽽且效率也会⼤⼤提升。
      时间复杂度:虽然代码是两层循环,但是我们的left 指针和right 指针都是不回退的,两者
      最多都往后移动n 次。因此时间复杂度是O(N) 。
    • 最后需要注意的一点就是,在一开始定义len的时候,由于题目中让我们找的是最小值,所以我们在给len赋值的时候,要赋值的是Integer的最大值.如果赋值为0,结果会一直是0.
  • 代码编写
class Solution {public int minSubArrayLen(int target, int[] nums) {int left = 0;int right = 0;int len = Integer.MAX_VALUE;//这里之所以要定义整数的最大值,是因为后面计算最小值的//时候,如果赋值为0,就一直是0int sum = 0;for (;right < nums.length;right++){sum += nums[right];while (sum >= target){len = Math.min(len,right - left + 1);//在刚好到达最小长度的时候,更新长度//之后出窗口的时候一直更新,直到不满足循环条件sum -= nums[left];left++;}}return len == Integer.MAX_VALUE? 0:len;}
}

3. 无重复字符的最长子串(难度:🔵2度)

OJ链接

  • 题目描述

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串
的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

  • 算法原理
    研究对象依然是一段区间,所以我们考虑使用滑动窗口.
    1. 定义Set来统计子串中都有哪些字符.
    2. 每有一个字符进入窗口,就判断个字符在不在Set中.
    3. 如果在,就让通过移动left指针让前面的元素出窗口,每出一个,就从Set中删除一个字符,直到Set中没有right指针指向的这个字符为止.
    4. 如果不在,就进入窗口,让Set中也增加这个字符.
  • 代码编写
class Solution {public int lengthOfLongestSubstring(String s) {Set<Character> set = new HashSet<>();//定义Set,用来统计区间内的字符int left = 0;int right = 0;int len = 0;for (;right < s.length();right++){while (set.contains(s.charAt(right))){//判断元素是否在区间中出现过set.remove(s.charAt(left));//每有元素出窗口,就从Set中删除left++;}set.add(s.charAt(right));//每有元素进入窗口,就加入Setlen = Math.max(len,right-left+1);}return len;}
}

4. 最大连续1的个数III(难度:🟡3度)

OJ链接

  • 题目描述

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。
示例 1:
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
示例 2:
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。

  • 算法原理
    • 这道题不要去想怎么把0转化为1
    • 因此,我们可以把问题转化成:求数组中⼀段最⻓的连续区间,要求这段区间内0 的个数不超过k 个。既然是连续区间,可以考虑使⽤「滑动窗口」来解决问题。
    • 让数组中的元素进入窗口,每进入一次窗口,就让表示最大长度的len++,如果进入的元素是0,那么就让统计0个数的zero++,当zero的个数大于了规定个数,就让区间之前的元素出窗口,直到0恢复正常个数.
  • 代码编写
class Solution {public int longestOnes(int[] nums, int k) {int left = 0;int right = 0;int len = 0;int zero = 0;for (;right < nums.length;right++){if (nums[right] == 0){zero++;}while (zero > k){if (nums[left] == 0){zero--;}left++;}len = Math.max(len,right-left+1);}return len;}
}

5. 将x减到0的最小操作数(难度:🟡3度)

OJ链接

  • 题目描述

给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。
示例 1:
输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。
示例 2:
输入:nums = [5,6,7,8,9], x = 4
输出:-1
示例 3:
输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。

  • 算法原理
    • 这道题最不好想的一点就是:这里的区间是数组两边的两个不连续的短区间,那么我们就有一种解决问题的办法正难则反.我们可以考虑把两个短区间通过使用数组长度减去,变成一个长区间.转化成求数组内⼀段连续的、和为 sum(nums) - x 的最长数组。此时,就是熟悉的「滑动窗⼝」问题了。
    • a. 转化问题:求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(int[] nums, int x) {int left = 0;int right = 0;int sum = 0;int sum1 = 0;int len = -1;for (int num:nums){sum += num;}int target = sum - x;if (target < 0){//如果数组的总和都不够达到x的,那么就不存在这样的数字//直接返回-1return -1;}for (;right < nums.length;right++){sum1 += nums[right];while (sum1 > target){sum1 -= nums[left];left++;}if (sum1 == target){len = Math.max(len,right-left+1);}}if (len == -1){return len;}else{return nums.length-len; }}
}

相关文章:

[算法] 优先算法(三):滑动窗口(上)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …...

[蓝桥杯 2020 省 A1] 超级胶水

一.题目 题目描述 小明有 n 颗石子&#xff0c;按顺序摆成一排。 他准备用胶水将这些石子粘在一起。 每颗石子有自己的重量&#xff0c;如果将两颗石子粘在一起&#xff0c;将合并成一颗新的石子&#xff0c;重量是这两颗石子的重量之和。 为了保证石子粘贴牢固&#xff0…...

读书笔记分享

1.苏格拉底只在需要的时候才索取&#xff0c;那样便能以最少的物质满足自身的要求。他认为每个人都天生体质脆弱&#xff0c;只有在贫乏的环境中才会锻炼地强壮起来。生活中的大多数人认为&#xff0c;奢华才是幸福的生活。无休止的物质积聚&#xff0c;让人们每天生活在一个内…...

考试宝典——软件过程与管理重点知识总结

概论 软件工程三要素 过程方法工具 软件过程的定义 软件过程是用于软件开发及维护的一系列活动、方法及实践。 常见软件过程分类&#xff08;五大类&#xff09; 客户-供应商过程&#xff1a;内部直接影响到客户、外部直接影响开发、向客户交付软件以及软件正确操作与使用的过…...

穿越时空的工厂之旅:探索可视化三维场景的奥秘

在科技日新月异的今天&#xff0c;我们似乎总是在不断追求着更加高效、智能的生产方式。 传统的工厂管理方式往往依赖于平面图纸、纸质文档和现场巡查&#xff0c;这不仅效率低下&#xff0c;而且容易出错。而三维可视化技术通过3D建模和虚拟现实技术&#xff0c;将工厂内部的各…...

2024年推荐的适合电脑和手机操作的线上兼职副业平台

总是会有人在找寻着线上兼职副业&#xff0c;那么在如今的2024年&#xff0c;互联网提供了诸多方便&#xff0c;无论你是宝妈、大学生、程序员、外卖小哥还是打工族&#xff0c;如果你正在寻找副业机会&#xff0c;那么这篇文章将为你提供一些适合电脑和手机操作的线上兼职副业…...

传感器的静态特性

传感器的静态特性是指传感器在稳态&#xff08;输入量为常量或变化极慢时&#xff09;输入信号作用下&#xff0c;传感器输出与输入信号之间的关系。这种关系一般用曲线、数学表达式或表格来表示。传感器的静态特性是传感器的基本特性之一&#xff0c;其描述了传感器在不考虑迟…...

如果jupyter notebook不能实现网页自动跳转,参考下面的链接

一招搞定Jupyter-notebook命令行打开之后不能自动跳转浏览器_一招搞定jupter notebook命令行打开之后-CSDN博客...

顺序表实现通讯录项目

目录 一.实现功能&#xff1a; 二.文件结构 三.代码实现 1.初始化 2.通讯录的销毁 3.通讯录添加数据 4.通讯录删除数据 5.通讯录的修改 6.展现通讯录数据 7.通讯录查找 四.代码 SeqList.h Contact.h Contact.c test(通讯录).c 一.实现功能&#xff1a; ⾄少能够存…...

【ai】pycharm设置软件仓库编译运行基于langchain的chatpdf

联想笔记本 y9000p创建python工程: 使用langchain支持openai的向量化embedding安装软件包 发现没有openai ,添加软件仓库打开工具窗口 点击设置...

LeetCode:279.完全平方数

class Solution:def numSquares(self, n: int) -> int:dp[i for i in range(n1)]for i in range(2,n1):for j in range(1,int(i**(0.5))1):dp[i]min(dp[i],dp[i-j*j]1)return dp[-1]代码解释 初始化 DP 数组&#xff1a; dp [i for i in range(n1)] 这里&#xff0c;dp[i]…...

Python面试宝典:Python中与ORM技术(对象关系映射)相关的面试笔试题(1000加面试笔试题助你轻松捕获大厂Offer)

Python面试宝典:1000加python面试题助你轻松捕获大厂Offer【第二部分:Python高级特性:第十五章:数据库编程:第二节:ORM技术】 第十五章:数据库编程第二节:ORM技术SQLAlchemyDjango ORMORM技术的优势和劣势python中与ORM技术相关的面试笔试题面试题1面试题2面试题3面试题…...

VUE3+TS+elementplus创建table,纯前端的table

一、前言 开始学习前端&#xff0c;直接从VUE3开始&#xff0c;从简单的创建表格开始。因为自己不是专业的程序员&#xff0c;编程主要是为了辅助自己的工作&#xff0c;提高工作效率&#xff0c;VUE的基础知识并不牢固&#xff0c;主要是为了快速上手&#xff0c;能够做出一些…...

UE驻网失败问题(二)

另一个UE注册失败的问题&#xff0c;具体过程如下&#xff1a; 问题现象如上&#xff0c;UE在这个N48上的小区一直在重复上述过程&#xff0c;收到RRC Setup后就不发RRC Setupcomplete&#xff0c;闭上眼睛也知道大概率是这个RRC Setup的配置有问题。 在问题时间点周围查看&…...

【MySQL】第三周作业

【MySQL】第三周作业 1、在数据库example下创建college表。2、在student表上创建视图college_view。3、查看视图college_view的详细结构4、 更新视图。5 、修改视图&#xff0c;6 、删除视图college_view 1、在数据库example下创建college表。 College表内容如下所示 字段名 …...

香橙派 Kunpeng Pro使用教程:从零开始打造个人私密博客

一、引言 在这个日益互联的世界中&#xff0c;单板计算机已经成为创新和个性化解决方案的重要载体。而在单板计算机领域&#xff0c;香橙派 Kunpeng Pro凭借其强大的性能和灵活的应用潜力&#xff0c;正逐渐吸引着全球开发者和技术爱好者的目光。 作为一款集成了华为的鲲鹏处…...

深入探索:中文字符的编码与转移字符的奥秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;探索字符编码的世界 二、字符编码基础&#xff1a;理解ASCII与Unicode…...

Ubuntu中 petalinux 安装 移植linux --tftp/tftp-hpa服务的方法

Xilinx 文档 PetaLinux 指南&#xff1a;如何创建 PetaLinux 环境 &#xff08;2019.1&#xff09; PetaLinux工具参考指南 PetaLinux安装详解(Xilinx , linux, zynq, zynqMP) petalinux 2020.1安装教程 一、PetaLinux工具和库安装 PetaLinux 工具要求主机系统 /bin/sh 为“b…...

JVM(内存区域划分、类加载机制、垃圾回收机制)

目录 一. 内存区域划分 1.本地方法栈(Native Method Stacks) 2.虚拟机栈(JVM Stacks) 3.程序计数器(Program Counter Register) 4.堆(Heap) 5.元数据区(Metaspace) 二.类加载机制 1.加载 2.验证 3.准备 4.解析 5.初始化 "双亲委派模型" 三. GC 垃圾回收…...

C语言---基础内容(万字)

C 语言是一种通用的、面向过程式的计算机程序设计语言。1972 年&#xff0c;为了移植与开发 UNIX 操作系统&#xff0c;丹尼斯里奇在贝尔电话实验室设计开发了 C 语言。 C 语言是一种广泛使用的计算机语言&#xff0c;它与 Java 编程语言一样普及&#xff0c;二者在现代软件程…...

告别网络延迟!AutoGLM-Phone-9B本地化部署实战,手机也能流畅对话AI

告别网络延迟&#xff01;AutoGLM-Phone-9B本地化部署实战&#xff0c;手机也能流畅对话AI 1. AutoGLM-Phone-9B简介与核心优势 1.1 专为移动端设计的轻量级大模型 AutoGLM-Phone-9B是一款革命性的多模态大语言模型&#xff0c;专为移动设备和边缘计算场景优化。与传统的云端…...

构建高性能WebSocket聊天应用:libwebsockets实战指南

构建高性能WebSocket聊天应用&#xff1a;libwebsockets实战指南 【免费下载链接】libwebsockets canonical libwebsockets.org networking library 项目地址: https://gitcode.com/gh_mirrors/li/libwebsockets Libwebsockets是一个简单易用、MIT许可证、纯C语言编写的…...

避坑指南:ROS2+PCL+LOAM建图定位中,点云格式、体素滤波与G2O链接的那些坑

ROS2PCLLOAM实战避坑指南&#xff1a;从点云处理到精准定位的完整解决方案 在机器人自主导航领域&#xff0c;激光SLAM技术凭借其高精度和稳定性成为工业级应用的首选方案。本文将深入剖析ROS2环境下基于PCL和LOAM的建图定位全流程&#xff0c;针对开发者实际遇到的12类典型问…...

李慕婉-仙逆-造相Z-Turbo 生成Matlab算法脚本:从数学公式到可执行代码

李慕婉-仙逆-造相Z-Turbo 生成Matlab算法脚本&#xff1a;从数学公式到可执行代码 最近在帮一个做信号处理的朋友调试代码&#xff0c;他给我看了一页论文里的公式&#xff0c;问我怎么在Matlab里实现。我盯着那一堆希腊字母和矩阵运算&#xff0c;突然想到&#xff0c;要是能…...

3大优势!Scarab模组管理工具使用技巧:从新手到高手的进阶指南

3大优势&#xff01;Scarab模组管理工具使用技巧&#xff1a;从新手到高手的进阶指南 【免费下载链接】Scarab An installer for Hollow Knight mods written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 你是否在安装空洞骑士模组时遇到过文件路…...

Mac开发者必看:如何同时管理Protobuf 2.6.1和3.19.4版本(附.proto文件编译避坑指南)

Mac开发者必看&#xff1a;如何同时管理Protobuf 2.6.1和3.19.4版本&#xff08;附.proto文件编译避坑指南&#xff09; 在跨版本协议开发中&#xff0c;Mac开发者常面临一个棘手问题&#xff1a;如何在同一台机器上同时维护Protobuf 2.6.1和3.19.4两个不兼容的版本&#xff1f…...

新手福音:在快马平台跟随交互式教程轻松搞定openclaw安装

最近在学习openclaw这个工具时&#xff0c;发现很多教程要么太简略&#xff0c;要么步骤不完整&#xff0c;对新手特别不友好。后来在InsCode(快马)平台上发现可以创建交互式教程项目&#xff0c;就尝试做了一个完整的openclaw安装指南。整个过程比我预想的顺利很多&#xff0c…...

终极视频修复指南:如何用Untrunc免费恢复损坏的MP4、MOV视频文件

终极视频修复指南&#xff1a;如何用Untrunc免费恢复损坏的MP4、MOV视频文件 【免费下载链接】untrunc Restore a damaged (truncated) mp4, m4v, mov, 3gp video. Provided you have a similar not broken video. 项目地址: https://gitcode.com/gh_mirrors/unt/untrunc …...

YOLOv11卷积模块深度剖析:从参数解析到实战应用

1. YOLOv11卷积模块设计精要 第一次接触YOLOv11的配置文件时&#xff0c;我和大多数开发者一样被那些看似简单却暗藏玄机的参数搞得一头雾水。特别是当我在backbone部分看到[-1, 1, Conv, [64, 3, 2]]这样的配置时&#xff0c;直觉告诉我输出通道数应该是64&#xff0c;但实际运…...

三步轻松搭建你的B站离线视频库:BilibiliDown完全使用指南

三步轻松搭建你的B站离线视频库&#xff1a;BilibiliDown完全使用指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirro…...