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

【LeetCode 算法专题突破】滑动窗口(⭐)

文章目录

  • 前言
  • 1. 长度最小的子数组
    • 题目描述
    • 代码
  • 2. 无重复字符的最长子串
    • 题目描述
    • 代码
  • 3. 最大连续1的个数 III
    • 题目描述
    • 代码
  • 4. 将 x 减到 0 的最小操作数
    • 题目描述
    • 代码
  • 5. 水果成篮
    • 题目描述
    • 代码
  • 6. 找到字符串中所有字母异位词
    • 题目描述
    • 代码
  • 7. 串联所有单词的子串
    • 题目描述
    • 代码
  • 总结

前言

学完了双指针算法,滑动窗口那肯定是逃不掉了,我个人感觉他俩就不分家,不把滑动窗口的题目好好刷上一刷我都难受

1. 长度最小的子数组

先来一道经典的滑动窗口试试水

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

题目描述


其实滑动窗口题目的解法都大同小异,我们基本上写几道题目,就能很好的掌握这个算法的思想了,来看代码:

代码

func minSubArrayLen(target int, nums []int) int {sum, len, n := 0, math.MaxInt32, len(nums)left, right := 0, 0for right < n {sum += nums[right]for sum >= target {len = min(len, right-left+1)sum -= nums[left]left++}right++}if len == math.MaxInt32 {return 0}return len
}func min(a, b int) int {if a > b {return b}return a
}

我写滑动窗口的题目时,一般会按照这样一个步骤来编写代码:

  1. 使用两个指针作为窗口的左右边界
  2. 右边界往右延伸,数组内容进窗口
  3. 左边界缩小范围,判断如何出窗口

这道题目相对容易,只需要关注 sum 和 target 是否匹配就行,之后遇到类似的题目就按照这样的解题思路来求解即可。

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

还是老样子,多做题,多思考,才能多进步

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

题目描述


这道题目其实一眼看过去,有很多解法,可以直接通过暴力解出来,也可以用滑动窗口来进行匹配,直接通过 set 去重,我之前用 C++ 做这道题的时候就是这么做的,但是在题解区学习了一下之后,我也用上了一个很巧妙而且复杂度最低的方法,来看代码:

代码

func lengthOfLongestSubstring(s string) int {win := [128]bool{}left, len := 0, 0for right, v := range s {for win[v] == true { // 出现了重复的字符,开始循环去重(代码的核心)win[s[left]] = falseleft++}win[v] = truelen = max(len, right-left+1)}return len
}func max(a, b int) int {if a > b {return a}return b
}

这段代码可以说也是非常的清晰易懂,这个代码最核心最精华,或者说设计最巧妙的地方就是在他使用了一个 bool 类型的数组来完成去重操作,和滑动窗口的遍历完美融合到了一起。

3. 最大连续1的个数 III

让我们再来一道题目,操练一下使用滑动窗口的能力

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

题目描述


这道题目乍一看,会发现有很多种情况需要考虑,最重要的其实就是思考 K 个 0 该怎么翻转才能实现出最多的连续 1,来看代码:

代码

func longestOnes(nums []int, k int) int {left, cnt0, len := 0, 0, 0for right, v := range nums {if v == 0 {cnt0++}for cnt0 > k {if nums[left] == 0 {cnt0--}left++}len = max(len, right-left+1)}return len 
}func max(a, b int) int {if a > b {return a}return b
}

虽然题目分析起来似乎有很多中情况需要考虑,但是我们可以把问题巧妙的转化一下,从翻转 k 个 0 转化成允许 1 数组中存在 k 个 0,这样这道题目就只需要单纯的计算连续为 1 的数组,然后顺便记录一下数组中 0 的个数即可,这也是代码中的 cnt0 变量的由来~

4. 将 x 减到 0 的最小操作数

我们话不多说,继续来刷下一道题

题目链接:1658. 将 x 减到 0 的最小操作数

题目描述

在这里插入图片描述
乍一看,如果我们直接从两边找 target = x 的数感觉会很麻烦,代码也不好写,那我们该怎么做呢?来看代码:

代码

func minOperations(nums []int, x int) int {left, right, sum, lenth, target := 0, 0, 0, math.MaxInt32, -xfor _, v := range nums {target += v}if target < 0 { // 如果全加上都达不到要求就直接返回return -1}for right < len(nums) { sum += nums[right]right++for sum > target {sum -= nums[left]left++}if sum == target {lenth = min(lenth, len(nums)-(right-left))}}if lenth == math.MaxInt32 {return -1}return lenth
}func min(a, b int) int {if a > b {return b}return a
}

我们可以将问题转化一下,把问题转化成:找出最长的中间子数组,这样我们就能求出最少需要使用的步骤了,也就能使用滑动窗口来解题了,这里我们就是把 target 设置为:数组总和 - x,这样当我们的子数组和 sum == target 的时候,就是符合题目要求的情况了
做了几道滑动窗口的题目之后,我们发现其实滑动窗口算法真正难的不是代码的编写,代码写几遍发现都是同样的写法,真正有难度的是这么样把问题转化成可以使用滑动窗口算法的形式,那怎么样才能想到呢?没有捷径,只有多练,所以我们继续下一题~

5. 水果成篮

咱们继续来练习

题目链接:904. 水果成篮

题目描述


遇到像这种题目话很多的,其实不用管,直接抓关键词就行,读完题目其实很容易就能想到这道题目该怎么做了(有了前几道题目的经验),像这道题这样不需要转换问题思路就能直接做的,其实就非常简单了,来看代码:

代码

func totalFruit(fruits []int) int {win := map[int]int{}lenth, left := 0, 0for right, v := range fruits {win[v]++for len(win) > 2 {win[fruits[left]]--if win[fruits[left]] == 0 {delete(win, fruits[left])}left++}lenth = max(lenth, right-left+1)}return lenth
}func max(a, b int) int {if a > b {return a}return b
}

这里我们使用的是 map 来进行对水果数量的映射,这样比较方便,其实直接用一个数组来映射也是一样的。
咱们接着练习下一道题。

6. 找到字符串中所有字母异位词

题目链接:438. 找到字符串中所有字母异位词

题目描述


来看代码:

代码

func findAnagrams(s string, p string) (ans []int) {lens, lenp := len(s), len(p)if lenp > lens { // 如果 p 比 s 长就不用找了return}var wins, winp [26]intfor _, v := range p { winp[v-'a']++}left, right := 0, 0for right < lens {wins[s[right]-'a']++ // 入窗口right++if wins == winp {ans = append(ans, left)wins[s[left]-'a']-- // 出窗口left++}if right-left+1 > lenp {wins[s[left]-'a']-- // 出窗口left++}}return ans
}

这道题在我的解法中,需要注意的是,在我们缩窗口的时候记得要让 wins 的字母出窗口,所以就有两个需要出窗口的地方,让 wins 的大小和 winp 始终保持一致,这样就能把所有情况都比较一遍

7. 串联所有单词的子串

刷了这么多题目,最后必须得来一道 hard 证明一下自己~

题目链接:30. 串联所有单词的子串

题目描述


来看代码:

代码

func findSubstring(s string, words []string) (ans []int) {if len(words) == 0 {return ans}slen, wlen, clen := len(s), len(words), len(words[0])if slen < clen*wlen {return ans}cmp := map[string]int{}for _, v := range words { // 用于比较的 cmpcmp[v]++}for i:= 0; i < clen; i++ {cnt, win := 0, map[string]int{}for left, right := i, i; right <= slen-clen; right+=clen {word := s[right:right+clen] // 截取单词 word,一个个进行匹配if num, _ := cmp[word]; num != 0 { // 存在 word 这个单词for win[word] >= num { // 如果这个 word 数量超过预期,就出窗口win[s[left:left+clen]]--cnt--left+=clen}win[word]++ // 入窗口 + 计数cnt++} else { // 不存在 word 这个单词for left < right { // 比较中断了,全部 word 出窗口win[s[left:left+clen]]--cnt--left+=clen}left+=clen // 让 left = right 重新开始(因为最后 right 会 += clen)}if cnt == wlen {ans = append(ans, left)}}}return ans
}

这道题目的思路和上一道题非常的像,但是代码的编写难度要高不少,我还是使用一样的思路,对每一个单词进行比较,具体的操作流程如下:

  1. 将需要比较的单词存进 cmp
  2. 因为每个单词的长度相同,所以遍历 len(words) 就能得出所有情况
  3. 接着设置 left,right 遍历整个 s
  4. 然后就开始逐个单词进行匹配,再根据计数求是否符合题目要求

总结

滑动窗口专题的一些经典题目就告一段落啦,如果什么时候对滑动窗口算法的思路亦或者是写代码的方法有疑问,就可以回来重新刷一遍,相信日后再遇到能够使用滑动窗口的题目都能游刃有余,轻松解决~

相关文章:

【LeetCode 算法专题突破】滑动窗口(⭐)

文章目录 前言1. 长度最小的子数组题目描述代码 2. 无重复字符的最长子串题目描述代码 3. 最大连续1的个数 III题目描述代码 4. 将 x 减到 0 的最小操作数题目描述代码 5. 水果成篮题目描述代码 6. 找到字符串中所有字母异位词题目描述代码 7. 串联所有单词的子串题目描述代码 …...

按键中断控制LED灯亮灭

EXTI—外部中断/事件控制器 EXTI&#xff08;External interrupt/event controller&#xff09;—外部中断/事件控制器&#xff0c;管理了控制器的 20 个中断/事 件线。每个中断/事件线都对应有一个边沿检测器&#xff0c;可以实现输入信号的上升沿检测和下降沿的 检测。EXTI可…...

YOLOV8目标检测——模型训练

文章目录 1下载yolov8&#xff08;[网址](https://github.com/ultralytics/ultralytics)&#xff09;2用pycharm打开文件3训练自己的YOLOV8数据集4run下运行完了之后没有best.pt文件5导出为onnx文件 本章内容主要解决如何训练自己的YOLOV8模型。 1下载yolov8&#xff08;网址&a…...

利用dockerfile升级flink的curl

最近Nusses扫出flink镜像有CURL漏洞&#xff0c;才发现要更新到最新版本 8.4.0&#xff0c;笔者当时flink版本为&#xff1a; flink:1.17.1-scala_2.12-java8 官方镜像仓库&#xff1a;https://hub.docker.com/_/flinkapt源 我试了如上2种方法&#xff0c;都不能更新curl到8…...

element 日期选择器禁止选择指定日期前后时间

画圈重点&#xff1a;disabledDate的写法要用箭头函数&#xff0c;不能用普通函数写法&#xff0c;否则this指向就错了&#xff0c;会报 undefined <el-date-picker v-model"time" type"date" value-format"yyyy-MM-dd" :…...

00TD时尚女童睡衣,蕾丝边+蝴蝶结太好看了

甜美又可爱的蕾丝花边加蝴蝶结 真的一下子戳中了我的心巴&#xff0c; 满满的少女风真的很好看&#xff0c; 妥妥的可爱小公主一枚 柔软又亲肤&#xff0c;厚厚的很保暖 睡觉真的很舒服 还有袖口和裤脚都做了松紧设计哟&#xff01;...

网络基础知识点

osi七层模型&#xff1a; 应用层&#xff1a;提供用户接口&#xff0c;与用户进行交互 表示层&#xff1a;进行数据格式的转换 会话层&#xff1a;建立、维护和验证会话 传输层&#xff1a;保证目标从源到目的地的传输&#xff08;传输协议和端口号&#xff09; 网络层&#x…...

力扣每日一题54:螺旋矩阵

题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#…...

基于WebRTC的程序因虚拟内存不足导致闪退问题的排查以及解决办法的研究

目录 1、WebRTC简介 2、问题现象描述 3、将Windbg附加到目标进程上分析 3.1、Windbg没有附加到主程序进程上&#xff0c;没有感知到异常或中断 3.2、Windbg感知到了中断&#xff0c;中断在DebugBreak函数调用上 3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 …...

2023年9月青少年软件编程(C 语言) 等级考试试卷(三级)

2023年9月青少年软件编程&#xff08;C 语言&#xff09; 等级考试试卷&#xff08;三级&#xff09;含答案 1.谁是你的潜在朋友 题目描述 “臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为一个宅男&#xff0c;你…...

用节点亲和性把 Pod 分配到节点

用节点亲和性把 Pod 分配到节点 当前集群信息&#xff1a; rootk8s-master:~# kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME k8s…...

GB28181学习(十)——视音频文件下载

要求 SIP服务器接收到媒体接收者发送的视音频文件下载请求后向媒体流发送者发送媒体文件下载命令&#xff0c;媒体流发送者采用RTP将视频流传输给媒体流接收者&#xff0c;媒体流接收者直接将视频流保存为媒体文件&#xff1b;媒体流接收者或SIP服务器可通过配置查询等方式获取…...

2023 年和 2024 年 10 个最佳加密货币趋势

1.熊市低迷 加密货币市场已进入持续数月的长期看跌阶段。尽管 2023 年初出现了一些看涨走势&#xff0c;但大多数领先的加密货币随后都出现了看跌低迷&#xff0c;导致其市值大幅下跌。 此外&#xff0c;持续的熊市可归因于一系列因素&#xff0c;包括宏观经济不确定性、利率…...

0026【Edabit ★☆☆☆☆☆】Convert Hours and Minutes into Seconds

0026【Edabit ★☆☆☆☆☆】Convert Hours and Minutes into Seconds language_fundamentals math Instructions Write a function that takes two integers (hours, minutes), converts them to seconds, and adds them. Examples convert(1, 3) // 3780 convert(2, 0) //…...

Java 枚举类

一、枚举类简介 1、枚举类概念 类的对象只有有限个且确定的&#xff0c;这种类称之为枚举类&#xff1b;因为在jdk1.5之前没有enum关键字来定义枚举类&#xff0c;只能采用class定义一个类然后将类做一些修改满足对象个数有限且确定&#xff0c;那么这种类就是枚举类&#xf…...

SQL sever中的存储过程

在Oracle的专篇中我也有仔细总结了存储过程的相关内容&#xff0c; 文章链接&#xff1a;http://t.csdnimg.cn/Z8AnH 尽管Oracle和SQL sever之间是存在一些区别&#xff0c;但许多基本的概念和原则在Oracle和SQL Server之间是通用的。它们之间有一些常见的区别&#xff0c;如下…...

spacy.load(“en_core_web_trf“)报错TypeError: issubclass() arg 1 must be a class

使用spacy时遇到的问题 写在最前面&#xff1a; 安装spacy和en_core_web_trf时需要保证二者版本一致 安装及查看对应spacy版本 安装 pip install spacy查看版本 import spacy spacy.__version__安装en_core_web_trf 直接安装&#xff08;如果可以的话&#xff09; pytho…...

【C++和数据结构】模拟实现哈希表和unordered_set与unordered_map

目录 一、哈希的概念与方法 1、哈希概念 2、常用的两个哈希函数 二、闭散列的实现 1、基本结构&#xff1a; 2、两种增容思路 和 插入 闭散列的增容&#xff1a; 哈希表的插入&#xff1a; 3、查找 4、删除 三、开散列的实现 1、基本结构 2、仿函数Hash 3、迭代器…...

十四天学会C++之第五天:类的详细讨论

1. 友元函数和友元类 什么是友元函数和友元类&#xff0c;它们的作用。如何声明和使用友元函数和友元类&#xff0c;访问类的私有成员。 友元函数&#xff08;Friend Functions&#xff09; 友元函数是一种特殊的函数&#xff0c;它被允许访问类的私有成员。这意味着即使成员…...

字典树学习笔记

trie 树&#xff0c;即字典树&#xff0c;是一种可以实现 O ( S ) O(S) O(S) 的预处理&#xff08; S S S 为所有字符串的长度和&#xff09;&#xff0c; O ( N ) O(N) O(N)&#xff08; N N N 为查询的字符串的长度&#xff09;的查询的数据结构。 举个栗子&#xff0c;对于…...

【vLLM 学习】Cpu Offload Lmcache

vLLM 是一款专为大语言模型推理加速而设计的框架&#xff0c;实现了 KV 缓存内存几乎零浪费&#xff0c;解决了内存管理瓶颈问题。 更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/ *在线运行 vLLM 入门教程&#xff1a;零基础分步指南 源码 examples/offline_inf…...

【SSM】SpringBoot笔记2:整合Junit、MyBatis

前言&#xff1a; 文章是系列学习笔记第9篇。基于黑马程序员课程完成&#xff0c;是笔者的学习笔记与心得总结&#xff0c;供自己和他人参考。笔记大部分是对黑马视频的归纳&#xff0c;少部分自己的理解&#xff0c;微量ai解释的内容&#xff08;ai部分会标出&#xff09;。 …...

Podman 和 Docker

Podman 和 Docker 都是容器化工具&#xff0c;用于创建、运行和管理容器。它们有很多相似之处&#xff0c;但也存在关键区别。下面从多个维度对比它们&#xff0c;并给出适用场景建议。 1. 核心区别 特性DockerPodman守护进程&#xff08;Daemon&#xff09;必须运行 dockerd …...

OpenLayers 地图定位

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图定位功能很常见&#xff0c;在移动端和PC端都需要经常用到&#xff0c;像百度、高德、谷歌都提供了方便快捷的定位功能。OpenLayers中也提供了定位的…...

解决uniapp开发app map组件最高层级 遮挡自定义解决底部tabbar方法

subNvue&#xff0c;是 vue 页面的原生子窗体&#xff0c;把weex渲染的原生界面当做 vue 页面的子窗体覆盖在页面上。它不是全屏页面&#xff0c;它给App平台vue页面中的层级覆盖和原生界面自定义提供了更强大和灵活的解决方案。它也不是组件&#xff0c;就是一个原生子窗体。 …...

【时时三省】(C语言基础)局部变量和全局变量

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 以前所见到的程序大多数是一个程序只包含一个main函数&#xff0c;变量是在函数的开头处定义的。这些变量在本函数范围内有效&#xff0c;即在本函数开头定义的变量&#xff0c;在本函数中可…...

【Zephyr 系列 11】使用 NVS 实现 BLE 参数持久化:掉电不丢配置,开机自动加载

🧠关键词:Zephyr、NVS、非易失存储、掉电保持、Flash、AT命令保存、配置管理 📌目标读者:希望在 BLE 模块中实现掉电不丢配置、支持产测参数注入与自动加载功能的开发者 📊文章长度:约 5200 字 🔍 为什么要使用 NVS? 在实际产品中,我们经常面临以下场景: 用户或…...

mysql+keepalived

文章目录 一、master1创建目录写入配置文件启动master1创建 `slave` 用户并授权获取主节点当前 `binary log` 文件名和位置position二、master2创建目录写入配置文件启动master2创建 `slave` 用户并授权获取主节点当前 `binary log` 文件名和位置position三、配置主主复制Maste…...

入门AJAX——XMLHttpRequest(Post)

一、前言 在上篇文章中&#xff0c;我们已经介绍了 HMLHttpRequest 的GET 请求的基本用法&#xff0c;并基于我提供的接口练习了两个简单的例子。如果你还没有看过第一篇文章&#xff0c;强烈建议你在学习完上篇文章后再学习本篇文章&#xff1a; &#x1f517;入门AJAX——XM…...

【递归、搜索与回溯】综合练习(四)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人递归&#xff0c;搜索与回溯算法的学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码…...