【LeetCode 算法专题突破】定长滑动窗口

文章目录

    • 前言
    • [1456. 定长子串中元音的最大数目](https://leetcode.cn/problems/maximum-number-of-vowels-in-a-substring-of-given-length/)
      • 题目描述:难度分1263
      • 代码与解题思路
      • 代码复盘
    • [2269. 找到一个数字的 K 美丽值](https://leetcode.cn/problems/find-the-k-beauty-of-a-number/)
      • 题目描述:难度分1280
      • 代码与解题思路
      • 代码复盘
    • [1984. 学生分数的最小差值](https://leetcode.cn/problems/minimum-difference-between-highest-and-lowest-of-k-scores/)
      • 题目描述:难度分1306
      • 代码与解题思路
      • 代码复盘
    • [643. 子数组最大平均数 I](https://leetcode.cn/problems/maximum-average-subarray-i/)
      • 题目描述:难度分(无)
      • 代码与解题思路
      • 代码复盘
    • [1343. 大小为 K 且平均值大于等于阈值的子数组数目](https://leetcode.cn/problems/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold/)
      • 题目描述:难度分1317
      • 代码与解题思路
      • 代码复盘
    • [2090. 半径为 k 的子数组平均值](https://leetcode.cn/problems/k-radius-subarray-averages/)
      • 题目描述:难度分1358
      • 代码与解题思路
      • 代码复盘
    • [2379. 得到 K 个黑块的最少涂色次数](https://leetcode.cn/problems/minimum-recolors-to-get-k-consecutive-black-blocks/)
      • 题目描述:难度分1360
      • 代码与解题思路
      • 代码复盘
    • [1052. 爱生气的书店老板](https://leetcode.cn/problems/grumpy-bookstore-owner/)
      • 题目描述:难度分1418
      • 代码与解题思路
      • 代码复盘
    • [2841. 几乎唯一子数组的最大和](https://leetcode.cn/problems/maximum-sum-of-almost-unique-subarray/)
      • 题目描述:难度分1546
      • 代码与解题思路
      • 代码复盘
    • [2461. 长度为 K 子数组中的最大和](https://leetcode.cn/problems/maximum-sum-of-distinct-subarrays-with-length-k/)
      • 题目描述:难度分1553
      • 代码与解题思路
      • 代码复盘
    • [1423. 可获得的最大点数](https://leetcode.cn/problems/maximum-points-you-can-obtain-from-cards/)
      • 题目描述:难度分1574
      • 代码与解题思路
      • 代码复盘
    • [2134. 最少交换次数来组合所有的 1 II](https://leetcode.cn/problems/minimum-swaps-to-group-all-1s-together-ii/)
      • 题目描述:难度分1748
      • 代码与解题思路
      • 代码复盘
    • [2653. 滑动子数组的美丽值](https://leetcode.cn/problems/sliding-subarray-beauty/)
      • 题目描述:难度分1786
      • 代码与解题思路
      • 代码复盘
    • [567. 字符串的排列](https://leetcode.cn/problems/permutation-in-string/)
      • 题目描述:难度分(无)
      • 代码与解题思路
      • 代码复盘
    • [438. 找到字符串中所有字母异位词](https://leetcode.cn/problems/find-all-anagrams-in-a-string/)
      • 题目描述:难度分(无)
      • 代码与解题思路
      • 代码复盘
    • 写在最后

前言

题目会根据顺序,难度逐渐上升。

“那些看似不起波澜的日复一日,会在某天让你看到坚持的意义。”

1456. 定长子串中元音的最大数目

题目描述:难度分1263

image-20240324181044654

代码与解题思路

思路比较简单,这里就不赘述了,之后思路比较简单明了的题目都不会过多分析题目

func maxVowels(s string, k int) int {l, r, n, cnt, ans := 0, 0, len(s), 0, 0for r < n {if check(s[r]) == true {cnt++}if r-l > k-1 { // 定长窗口, 所以可以用 if, 用 for 也行if check(s[l]) == true {cnt--}l++}r++ans = max(ans, cnt)} return ans
}func check(s byte) bool {return strings.Contains("aeiou", string(s))
}

代码复盘

这段代码有什么可以学习和积累的地方吗?

1、判断函数 check 使用:strings.Contains(“aeiou”, string(s)),巧妙的方式判断一个字符是否在一个字符集合中,以本题为例:用于判断当前字符是否是元音字母

2、定长滑动窗口如何判断是否达到题目要求的长度:if r-l > k-1 表明已经超过了题目要求的长度,可以 ”滑动“ 窗口了

3、每轮循环最后,稳定进行:r++ 和维护最大/最小值的行为

我们带着学习到的知识,继续做下一道题目

2269. 找到一个数字的 K 美丽值

题目描述:难度分1280

image-20240324181021974

代码与解题思路

func divisorSubstrings(num int, k int) int {s := strconv.Itoa(num)l, r, ans, n := 0, 0, 0, len(s)for r < n {t, _ := strconv.Atoi(s[l:r+1])if r-l == k-1 && check(num, t) == true { // 达到题目要求之后再 checkans++}if r-l == k-1 { // 在达到长度 k 之后, 每次都进行 l++ 和 r++, 保持前进l++}r++}return ans
}func check(num, t int) bool {if t == 0 { // t 不能为 0return false}return num%t == 0
}

代码复盘

依旧是使用同一个模板,但有些细节的地方需要注意

1、整数转字符串不能用 string(num) 而需要用 strconv.Itoa(num)

2、根据题目不同的情况和要求,注意判断 l 窗口边界移动的时机

3、使用取模运算的时候,计算的数字不能为 0

1984. 学生分数的最小差值

题目描述:难度分1306

image-20240324180956676

代码与解题思路

题目要求的是 k 个数之间的最高分和最低分的最小差值,在排序之后,让最右边的数 - 最左边的数,得到的就是这个区间最高分和最低分的差值了,再求所有区间的最小值就能求出题目要求的答案了

func minimumDifference(nums []int, k int) int {sort.Ints(nums)ans := nums[k-1] - nums[0]for i := k; i < len(nums); i++ {ans = min(ans, nums[i]-nums[i-k+1])}return ans
}

代码复盘

1、巧妙利用 i 作为滑动窗口右边界,i-k+1 作为滑动窗口左边界

2、对于示例一的特例,通过初始化 ans := nums[k-1] - nums[0] 来解决

643. 子数组最大平均数 I

题目描述:难度分(无)

image-20240324181113924

代码与解题思路

func findMaxAverage(nums []int, k int) float64 {l, r, n, sum, ans := 0, 0, len(nums), 0, -math.MaxInt/2for r < n {sum += nums[r]if r-l == k-1 {ans = max(ans, sum)sum -= nums[l]l++}r++}return float64(ans)/float64(k)
}

代码复盘

1、使用 -math.MaxInt/2 作为 ans 的初值,既能防止溢出,又能保证他作为最小值

2、巧妙完成题目返回 float64 的要求:直接在最后进行强转 float64(ans)/float64(k)

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

题目描述:难度分1317

image-20240324180932544

代码与解题思路

func numOfSubarrays(arr []int, k int, threshold int) (ans int) {l, r, n, sum := 0, 0, len(arr), 0for r < n {sum += arr[r]if r-l == k-1 {if sum/k >= threshold {ans++}sum -= arr[l]l++}r++}return ans
}

代码复盘

直接用模板秒了,非常典型

2090. 半径为 k 的子数组平均值

题目描述:难度分1358

image-20240325094348574

代码与解题思路

func getAverages(nums []int, k int) (ans []int) {l, r, n, sum := 0, 0, len(nums), 0for r < n {sum += nums[r]ans = append(ans, -1)if r-l == k*2 { // 窗口符合题目要求长度if k == 0 { // 特判 k = 0 的情况ans[r-k] = sum} else {ans[r-k] = sum/(k*2+1)}sum -= nums[l]l++}r++}return ans
}

代码复盘

同样是定长滑动窗口,相比之前的题目稍微灵活了一些,使用自己熟悉的模板,具体情况具体分析即可

2379. 得到 K 个黑块的最少涂色次数

题目描述:难度分1360

image-20240325095658481

代码与解题思路

func minimumRecolors(blocks string, k int) int {l, r, n, cnt, ans := 0, 0, len(blocks), 0, math.MaxInt/2for r < n {if blocks[r] == 'W' {cnt++}if r-l == k-1 {ans = min(ans, cnt)if blocks[l] == 'W' {cnt--}l++}r++}return ans
}

代码复盘

这次写代码又忘记 math.MaxInt 的拼写了,下次记住 mM 两个 m 打头

1052. 爱生气的书店老板

题目描述:难度分1418

image-20240325101915441

代码与解题思路

老板克制生气的时间,就是题目要求的滑动窗口的大小;老板不生气的时间就是基础的顾客人数数值;老板生气的时间,就是我们需要使用滑动窗口取人数最多的地方了。在老板克制生气的时间内找顾客最多的那个区间

func maxSatisfied(customers []int, grumpy []int, minutes int) int {l, r, n, sum, ans := 0, 0, len(customers), 0, -math.MaxInt/2for i, v := range customers {if grumpy[i] == 0 {sum += vcustomers[i] = 0 // 巧妙置零}}for r < n {sum += customers[r]if r-l == minutes-1 {ans = max(ans, sum)sum -= customers[l]l++}r++}return ans
}

代码复盘

在计算基础顾客数值的时候,将计算之后的顾客人数置为 0,后面使用滑动窗口的时候,就不需要进行 if grumpy[r] == 1 这样的判断了

2841. 几乎唯一子数组的最大和

题目描述:难度分1546

image-20240325110109864

代码与解题思路

这道题的重点就在,如何判断题目要求的所谓 “几乎唯一子数组”。用哈希判断即可,可以用数组模拟,也可以用语言自带的库。

func maxSum(nums []int, m int, k int) int64 {l, r, n, sum, ans, win := 0, 0, len(nums), int64(0), int64(0), map[int]int{}for r < n {win[nums[r]]++sum += int64(nums[r])if r-l == k-1 {if len(win) >= m {ans = max(ans, sum)}win[nums[l]]--if win[nums[l]] == 0 {delete(win, nums[l])}sum -= int64(nums[l])l++}r++}return ans
}

代码复盘

这道题是经典的哈希+滑窗,我也是第一次用 go 写这个类型,刚好可以积累积累 go 使用 map 的技巧:

1、go 的 map 可以用 len() 计算有多少个键值对

2、使用 delete(map, key) 可以删除 map 中键为 key 的键值对

2461. 长度为 K 子数组中的最大和

题目描述:难度分1553

image-20240325111457389

代码与解题思路

func maximumSubarraySum(nums []int, k int) int64 {l, r, n, sum, ans, win := 0, 0, len(nums), int64(0), int64(0), map[int]int{}for r < n {win[nums[r]]++sum += int64(nums[r])if r-l == k-1 {if len(win) == k {ans = max(ans, sum)}win[nums[l]]--if win[nums[l]] == 0 {delete(win, nums[l])}sum -= int64(nums[l])l++}r++}return ans
}

代码复盘

我的评价是跟上一道题目一毛一样,而且题目描述比上一道说的更加 “人话”。把 m 改成了 k 就过了。

1423. 可获得的最大点数

题目描述:难度分1574

image-20240325113654229

代码与解题思路

题目说可以从行的开头或者结尾拿一张卡牌,求点数的最大和。由于我们只能从开头或末尾拿牌,所以最后剩下的牌必然是连续的,通过逆向思维,我们可以用滑动窗口求剩下的连续的卡牌的最小和,就能得出点数的最大和了。

func maxScore(cardPoints []int, k int) int {l, r, n, sumMin, sum, ans := 0, 0, len(cardPoints), 0, 0, math.MaxInt/2for r < n {sum += cardPoints[r]sumMin += cardPoints[r]if r-l == n-k-1 {ans = min(ans, sumMin)sumMin -= cardPoints[l]l++}r++}if k == len(cardPoints) { // 拿起所有卡牌return sum}return sum-ans
}

代码复盘

通过总数 sum - ans 最小和,我们就能求出题目要求的最大和。

2134. 最少交换次数来组合所有的 1 II

题目描述:难度分1748

image-20240325141314180

代码与解题思路

这道题目也需要理解题目的要求,对题目的信息进行转化。题目要将所有 1 都聚集在一起,最差的情况我们需要把每个 1 都移动一遍,那我们可以让 1 的数量作为滑动窗口的大小,窗口中 1 存在的越多,证明需要移动的 1 就越少(窗口中全是 1 就是最后的答案)

func minSwaps(nums []int) int {k := 0for _, v := range nums {k += v}nums = append(nums, nums...) // 环形数组l, r, ans, sum, n := 0, 0, 0, 0, len(nums)for r < n { // 滑动窗口if nums[r] == 1 {sum++}if r-l == k-1 {ans = max(ans, sum)if nums[l] == 1 {sum--}l++}r++}return k-ans
}

代码复盘

1、使用 nums = append(nums, nums…) 将数组本身追加一份到数组后面,可以处理环形数组的问题

2653. 滑动子数组的美丽值

题目描述:难度分1786

image-20240325150216936

代码与解题思路

这道题目的核心就在于,怎么判断一个数是不是美丽值,题目要求找倒数第 x 个数,如果每个都排序肯定会超时,也许可以用堆来维护区间内的单调性,但堆我用的不多,而且 go 的堆比较麻烦,我也没有什么好的思路

这道题目有一个可以利用的地方,他数据范围给了 -50~50,非常小,通过这个性质对整个数据范围进行计数,每次判断的时候:让 x 逐个减去当前值的个数,当 x < 0 或者 x = 0 的时候,证明当前这个数就是题目要找的美丽值了

func getSubarrayBeauty(nums []int, k int, x int) []int {cnt := [110]int{}   l, r, n := 0, 0, len(nums)ans := make([]int, n-k+1)for r < n {cnt[nums[r]+50]++if r-l == k-1 {t := xfor i, v := range cnt[:50] {t -= vif t <= 0 { // 当前这个数是美丽值ans[l] = i-50break}}cnt[nums[l]+50]--l++}r++}return ans
}

代码复盘

1、注意观察题目的数据范围,说不定有可以利用的地方,就像本题利用计数排序的思想巧妙求出倒数第 x 个数

567. 字符串的排列

题目描述:难度分(无)

image-20240325160641166

代码与解题思路

如何判断是两个子串是相同的排列是这道题的核心问题,我们可以通过 cnt 数组记录每个字母的个数,遍历的时候–,如果此时的 cnt 数组内都是正数,就证明这两个子串字符的数量相同,即符合题目的条件

func checkInclusion(s1 string, s2 string) bool {cnt, l, r, n := make([]int, 26), 0, 0, len(s2)for _, v := range s1 {cnt[v-'a']++}for r < n {cnt[s2[r]-'a']--if r-l == len(s1)-1 {flag := 0for _, v := range cnt {if v < 0 {flag = 1}}if flag == 0 {return true}cnt[s2[l]-'a']++l++}r++}return false
}

代码复盘

1、Golang 也能通过 ‘a’ - ‘a’ 的形式获取到数字 0,通过这个性质我们可以构建字符数组 cnt

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

题目描述:难度分(无)

image-20240325162036690

代码与解题思路

这道题跟上一道题几乎一模一样,稍微修改,把下标存入数组返回即可

func findAnagrams(s string, p string) (ans []int) {cnt, l, r, n := make([]int, 26), 0, 0, len(s)for _, v := range p {cnt[v-'a']++}for r < n {cnt[s[r]-'a']--if r-l == len(p)-1 {flag := 0for _, v := range cnt {if v < 0 {flag = 1}}if flag == 0 {ans = append(ans, l)}cnt[s[l]-'a']++l++}r++}return ans
}

代码复盘

同样的题目思路,无复盘

写在最后

题单还有两道困难题,因为超出能力范围所以暂时搁置

2156. 查找给定哈希值的子串 难度分2063

2953. 统计完全子字符串 难度分2449

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

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

相关文章

NAT---网络地址转换技术

Network Address Translation 1、起源&#xff1a;ip地址不够用 2、作用&#xff1a;让私网地址映射成公网地址&#xff0c;进而访问网络。 3、私网Ip地址的范围&#xff1a; A类&#xff1a;10.0.0.0-10.255.255.255 B类&#xff1a;172.16.0.0-172.31.255.255 C类&…

码垛机与人工搬运:效率与安全性的比较分析

在现代包装行业中&#xff0c;泡沫箱因其轻便和保温特性被广泛用于商品的包装与运输。随着自动化技术的不断发展&#xff0c;码垛机成为提升泡沫箱生产效率、降低劳动强度的关键技术。本文旨在比较码垛机与人工码垛在泡沫箱生产中的优势&#xff0c;并探讨自动化码垛的未来发展…

Springboot快速整合bootstrap-table使用,接口对接

这个表格加持还是不错了&#xff0c;自带了全局搜索&#xff0c;分页&#xff0c;数据导出&#xff0c;卡片视图&#xff0c;等&#xff0c;本次整合添加了数据添加弹窗和编辑数据回显弹窗&#xff0c;附完整页面代码&#xff0c;只需要拿过来替换自己实际的接口即可。 效果图 …

鸿蒙实战开发-如何通过拖动滑块调节应用内字体大小

介绍 本篇Codelab将介绍如何使用基础组件Slider&#xff0c;通过拖动滑块调节应用内字体大小。要求完成以下功能&#xff1a; 实现两个页面的UX&#xff1a;主页面和字体大小调节页面。拖动滑块改变字体大小系数&#xff0c;列表页和调节页面字体大小同步变化。往右拖动滑块字…

ppp验证实验

实际操作图 1&#xff0c;IP划分分配 [r1]interface Serial 4/0/0 [r1-Serial4/0/0]ip add 192.168.1.1 24 [r2]interface Serial 4/0/0 [r2-Serial4/0/0]ip address 192.168.1.2 24 [r2]int Mp-group 0/0/0 [r2-Mp-group0/0/0]ip add 192.168.2.1 24 [r3]int Mp-group 0/…

Xcode Launching “XXX“ is taking longer than expected

文章目录 1.问题2.如何进入iOS DeviceSupport目录3.解决方法4.参考博客 1.问题 LLDB is likely reading from device memory to resolve symbols 2.如何进入iOS DeviceSupport目录 3.解决方法 进入iOS DeviceSupport目录&#xff0c;删除该真机对应的架构文件&#xff08;比如…

QT作业day3

1、使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是…

JMeter 如何并发执行 Python 脚本

要在JMeter中并发执行Python脚本&#xff0c;可以使用Jython脚本或通过调用外部Python脚本的方式实现。 使用Jython脚本并发执行Python脚本的步骤&#xff1a; 1、创建一个线程组&#xff1a;在JMeter界面中&#xff0c;右键点击测试计划&#xff0c;选择 “添加” -> “线…

c语言文件操作(下)

目录 1.文件的随机读写1.1 fseek1.2 ftell1.3 rewind 2. 文件结束的判定2.1 文本文件读取结束的判断2.2 二进制文件读取结束的判断 3. 文件缓冲区 1.文件的随机读写 1.1 fseek 根据⽂件指针的位置和偏移量来定位⽂件指针。 函数原型&#xff1a; int fseek (FILE * stream,…

Springboot+vue的企业质量管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的企业质量管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09…

黑马头条day5总结

1、surefire-reports for the individual test results. 借鉴&#xff1a;【已解决】surefire-reports for the individual test results.-CSDN博客 Please refer to D:\javashizhan01\heima-leadnews\heima-leadnews-service\heima-leadnews-article\target\surefire-report…

HTML(二)---【常见的标签使用】

零.前言 本文只介绍常见的标签使用&#xff0c;其中使用的一些HTML专业术语可以在作者的第一篇文章&#xff1a; HTML&#xff08;一&#xff09;---【基础】-CSDN博客中找到。 一.<b>粗体、<i>或<em>斜体 1.定义 粗体、斜体的实现可以在CSS中实现&…

【MySQL】事务日志

事务的隔离性由锁机制实现&#xff0c;事务的原子性、一致性和持久性由redo日志和undo日志实现。 一、redo日志 1.1、为什么需要redo日志 一方面&#xff0c;由于数据从内存写回磁盘需要一定的时间&#xff0c;假如在事务提交后&#xff0c;还没有写回磁盘&#xff0c;数据库…

web前端面试题---->HTML、CSS

一.居中方法 block元素如何居中 margin&#xff1a;0 auto&#xff1b;position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);flex布局&#xff1a; 对父元素操作 &#xff1a; justify-content:center; al…

商城小程序项目实现监控的可观测性最佳实践

前言 微信小程序是一种轻量级的应用程序&#xff0c;用户可以在微信内直接使用&#xff0c;无需下载安装。它具有独立的开发框架和生态系统&#xff0c;支持丰富的功能和交互&#xff0c;包括社交、购物、服务等。 观测云对微信小程序的监控能够实时收集性能指标、错误日志和…

分布式系统CAP理论

1、什么是CAP理论 C是Consistency(强一致性)、A是Availability(可用性)、P是Partition Tolerance(分区容错性)&#xff0c;一个分布式系统不可能同时很好的满足—致性、可用性和分区容错性这三个需求&#xff0c;不能同时成立&#xff0c;最多只能同时满足其中的两项&#xff…

Linux系统运维命令:找出某个分区或者路径下 占用磁盘空间最多的文件和目录

目录 一、需求 二、解决方法 1、解决思路 2、组合命令 3、du命令 三、实例演示和命令解释 1、实例演示 &#xff08;1&#xff09;查看当前路径下文件和目录 &#xff08;2&#xff09;命令效果展示 2、命令解释 &#xff08;1&#xff09;. du -cks &#xff08;2…

小白学视觉 | 图像上的 OpenCV 算术运算

本文来源公众号“小白学视觉”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;图像上的 OpenCV 算术运算 1 OpenCV 简介 图像可以进行算术运算&#xff0c;例如加法、减法和按位运算&#xff08;AND、OR、NOT、XOR&#xff09;。…

电商系列之仓储发货

疫情3年&#xff0c;大多数人都将购买需求转移到了线上。同时由于暴涨的订单数量、还在恢复中的物流运输等因素&#xff0c;导致用户的收货时间缓慢甚至是发货时间、收货时间延后。那么笔者就从订单的仓库作业流程入手&#xff0c;分析了用户订单发货延后的原因。 受到最近疫情…

简历工具推荐

HR浏览一份简历也就25秒左右&#xff0c;如果你连「好简历」都没有&#xff0c;怎么能找到好工作呢&#xff1f; 以最简单的方式来写好简历&#xff0c;只需专注内容本身而无需关注排版。这样的效果才是我们想要的&#xff0c;这里推荐使用入职啦简历&#xff0c;这个工具最大的…