Leetcod面试经典150题刷题记录 —— 滑动窗口篇

滑动窗口篇

    • 1. 长度最小的子数组
      • Python3
    • 2. 无重复字符的最长子串
    • 3. 串联所有单词的子串
      • 3.1 *(本题前导题)* 找到字符串中所有字母异位词
      • 本题
    • 4. 最小覆盖子串
      • 官方解法
      • 优化解法(我写的不太成功,并未加速)

滑动窗口就像一只蠕动的蚯蚓,头部前进,尾部蓄力,和双指针天生一对。

1. 长度最小的子数组

题目链接:长度最小的子数组 - leetcode
题目描述:
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [ n u m s l nums_l numsl, n u m s l + 1 nums_{l+1} numsl+1, …, n u m s r − 1 nums_{r-1} numsr1, n u m s r nums_r numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
题目归纳:
(1)子数组总和 >= target
(2)子数组要连续 [nums_l, nums_(l+1), … , nums_(r-1), nums_r]
(3)长度为r-(l-1),值要最小
(4)数组的值均为正整数,所以只管考虑相加

解题思路:
(1) 解法: 见代码。

Python3

class Solution:def minSubArrayLen(self, target: int, nums: List[int]) -> int:# (1)子数组总和 >= target# (2)子数组要连续 [nums_l, nums_(l+1), ... , nums_(r-1), nums_r]# (3)长度为r-(l-1),值要最小# (4)数组的值均为正整数,所以只管考虑相加# sum[i] = sum (nums[0] + ... + nums[i])# 那么子数组[nums_l, nums_(l+1), ... , nums_(r-1), nums_r]的和就会等于 sum[r] - sum[l-1]# 与 盛最多水容器 一题类似,移动值更小的边界指针n = len(nums)if(n == 0):return 0l, r = 0, 0ans_len = 1e9sums = 0while r < n:sums += nums[r]while sums >= target: # 这里的l+=1移动值得玩味ans_len = min(ans_len, r-(l-1))sums -= nums[l]l += 1r += 1if ans_len == 1e9: # 说明所有数组元素加起来都小于targetreturn 0else:return ans_len

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

题目链接:无重复字符的最长子串 - leetcode
题目描述:
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
题目归纳:
(1)如果依次递增地枚举子串的起始位置,那么子串的结束位置也是递增的

解题思路:
(1) 解法: 见代码。

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:hash_set = set()n = len(s)right, ans = -1, 0for i in range(n):if i > 0:hash_set.remove(s[i-1]) # 移除起始处前一个位置的元素while right + 1 < n and s[right+1] not in hash_set: # 下一个元素不重复,循环这个过程hash_set.add(s[right+1])right += 1 # 真正右移ans = max(ans, right-i+1)return ans

3. 串联所有单词的子串

3.1 (本题前导题) 找到字符串中所有字母异位词

题目链接:找到字符串中所有字母异位词 - leetcode
题目描述:
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
s 和 p 仅包含小写字母

题目归纳:
题意不难理解。第一步,如果给你两个字符串,长度一致,各字符数量一致,这两个字符串即互为异位词。第二步,滑动窗口寻找。建一个和 p p p串长度相同的滑动窗口,在 s s s中滑动,那么只要这个窗口字符数量与 p p p一致,即为异位词。

解题思路:
(1) 解法: 找到字符串中所有字母异位词 - leetcode官方题解

# (1)python原生写法,数组统计词频
class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:s_len, p_len = len(s), len(p)if s_len < p_len:return []ans = []s_count = [0]*26p_count = [0]*26for i in range(p_len):p_count[ord(p[i]) - 97] += 1 # ord()返回对应的unicode编码,97是a的ASCII码值s_count[ord(s[i]) - 97] += 1 if (s_count == p_count): # 词频数组相等ans.append(0) # 开头位置就是答案之一for i in range(1,s_len - p_len+1) : # 滑动窗口的起始位置,最多不会超过s_len - p_lens_count[ord(s[i-1]) - 97] -= 1  # 滑动窗口向右滑动中s_count[ord(s[i+p_len-1]) - 97] += 1 # 滑动窗口向右滑动,下一个要包括的字符词频+1if s_count == p_count:ans.append(i) return ans
# (2)python中的collections写法,Counter()类统计词频
from collections import Counter # leetcode刷题时,最好把引用也写上,避免到时引用类没有自动提示class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:s_len, p_len = len(s), len(p)if s_len < p_len:return []ans = []s_count = Counter() # Counter()类统计词频,十分好用p_count = Counter()for i in range(p_len):p_count[p[i]] += 1s_count[s[i]] += 1if (s_count == p_count): # 词频数组相等ans.append(0) # 开头位置就是答案之一for i in range(1,s_len - p_len+1) : # 滑动窗口的起始位置,最多不会超过s_len - p_lens_count[s[i-1]] -= 1s_count[s[i+p_len-1]] += 1if s_count == p_count:ans.append(i) return ans

本题

题目链接:串联所有单词的子串 - leetcode
题目描述:
给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。例如,如果 words = ["ab","cd","ef"], 那么 "abcdef""abefcd""cdabef""cdefab""efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。
题目归纳:
在有了前导题的基础上,乍一看可以用全排列,先将数组中的子串组合情况全部列出来,然后放入字符串s中进行s.find(sub_str)进行查找,但是这种方式的时间复杂度太高,达到了 O ( n ! ) O(n!) O(n!) n n n是数组长度。

解题思路:
(1) 解法: 串联所有单词的子串 - leetcode官方题解

from collections import Counter # leetcode刷题时,最好把引用也写上,避免到时引用类没有自动提示class Solution:def findSubstring(self, s: str, words: List[str]) -> List[int]:# 第438题的元素是字母,此题的元素是单词。438题是求异位词,而这里是求异位字符串res = []m = len(words)n = len(words[0]) # 每个单词长度一致s_len = len(s)window_len = m*nfor i in range(n):if i + window_len > s_len: # i+偏移量若>s_len则越界,这里偏移量为words长度,即窗口长度m*nbreak# Counter()类用法: # (1)https://blog.csdn.net/weixin_67683316/article/details/127079849 # (2)https://docs.python.org/3/library/collections.html#collections.Counter# 这道题中,Counter()也可以理解为hash表,只是更便于调用,用dict()实现也是一样的differ = Counter() # 一、对s进行切片,每个切片长度为n,这样才是类似于字母异位词的搜寻。# 划分方法为,先删去前i个字母,再对剩余字母进行切片长度为n的划分,若划分至末尾字母长度不足n,也删去for j in range(m):word = s[i + j*n : i + (j+1)*n]# 初始化differ时,出现在窗口中的单词,每出现一次,相应的值+1,differ[word] += 1for w in words: # 这里遍历循环最好不要写成for word in words, 避免与上面产生阅读歧义# 出现在words中的单词,每出现一次,相应的值-1differ[w] -= 1if differ[w] == 0: # 词频不能低于0,必须删除,要么做减法时加限制条件del differ[w]# [i, i+n, i+2n,...,s_len - window_len]for start in range(i, s_len-window_len + 1, n): if start != i:# 窗口右移,右侧加入新词,左侧移出旧词,对differ做相应的更新new_word = s[start + window_len - n : start + window_len]differ[new_word] += 1if differ[new_word] == 0:del differ[new_word]old_word = s[start-n: start]differ[old_word] -= 1if differ[old_word] == 0:del differ[old_word]if len(differ) == 0: # 词频完全一致,则为串联子串,可以append此时索引res.append(start)return res

4. 最小覆盖子串

题目链接:最小覆盖子串 - leetcode
题目描述:
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 “BANC” 包含来自字符串 t 的 'A''B''C'

题目归纳:
测试用例保证答案唯一。

解题思路:
(1) 解法: 最小覆盖子串 - leetcode官方题解

官方解法

from collections import Counter # leetcode刷题时,最好把引用也写上,避免到时引用类没有自动提示class Solution:def check(self, window_counter: Counter, t_counter: Counter):# 如果window中的词频数量>=t,则是符合条件的if window_counter >= t_counter:return Trueelse:return Falsedef minWindow(self, s: str, t: str) -> str:# 查找s中,涵盖t所有字符的最小子串,像《找到字符串中所有字母异位词》的扩展# 《找到字符串中所有字母异位词》是目标长度必须相同,且字符频数也必须相同# 这道题只需要字符频数相同,长度可以>=,也就是说,这题的滑动窗口,window_len是不固定的# 解题思路# (1)称包含t的全部字母窗口,为"可行"窗口# (2)双指针l与r。窗口包含t串,左指针l右移,窗口不包含t串,右指针r右移。任意时刻,只有一个指针运动。# (3)此时要比较ans_len长度,若ans_len比之前更小,那么更新ans_len与ans。ans_len = r-(l-1)# (4)用Counter计算字符频率# (5)优化版本,官解未实现。精简无关字符串,就是扔掉一些无关子串,如s=XXABXXC, t=ABC,那么可以扔掉开头的两个XXs_len = len(s)t_len = len(t)if s_len < t_len:return ""window_counter = Counter() # 窗口字频词典t_counter = Counter() # t字频词典# (1)计算t中字符频率for ch in t:t_counter[ch] += 1# (2)双指针l, r = 0, 0ans_len = 1e9ans = ""while r < s_len:s_r = s[r]if r < s_len and t_counter[s_r] > 0: # r指针未越界,且当前字符在t_counter字频词典中window_counter[s_r] += 1 # 窗口中该字频+1while self.check(window_counter,t_counter) and l <= r: # 在s中找到了包含t的字符串window_len = r-l+1if window_len < ans_len: # 找到了更小的窗口长度ans_len = window_lenans = s[l: l+window_len]s_l = s[l]if t_counter[s_l] > 0: # 只在window_counter中,减去与t串相关的字符词频。window_counter[s_l] -= 1 # 左指针向右移动if window_counter[s_l] == 0: # 有无这行判断对求解无影响,为了严谨del window_counter[s_l]l += 1 # 窗口包含t串,左指针l右移r += 1 # 窗口不包含t串,右指针r右移return ans

优化解法(我写的不太成功,并未加速)

from collections import Counter # leetcode刷题时,最好把引用也写上,避免到时引用类没有自动提示class Solution:def check(self, window_counter: Counter, t_counter: Counter):# 如果window中的词频数量>=t,则是符合条件的if window_counter >= t_counter:return Trueelse:return Falsedef minWindow(self, s: str, t: str) -> str:# 查找s中,涵盖t所有字符的最小子串,像《找到字符串中所有字母异位词》的扩展# 《找到字符串中所有字母异位词》是目标长度必须相同,且字符频数也必须相同# 这道题只需要字符频数相同,长度可以>=,也就是说,这题的滑动窗口,window_len是不固定的# 解题思路# (1)称包含t的全部字母窗口,为"可行"窗口# (2)双指针l与r。窗口包含t串,左指针l右移,窗口不包含t串,右指针r右移。任意时刻,只有一个指针运动。# (3)此时要比较ans_len长度,若ans_len比之前更小,那么更新ans_len与ans。ans_len = r-(l-1)# (4)用Counter计算字符频率# (5)优化版本,官解未实现。精简无关字符串,就是扔掉一些无关子串,如s=XXABXXC, t=ABC,那么可以扔掉开头的两个XXs_len = len(s)t_len = len(t)if s_len < t_len:return ""window_counter = Counter() # 窗口字频词典t_counter = Counter() # t字频词典# (1)计算t中字符频率for ch in t:t_counter[ch] += 1# ()优化部分,可选。    faster_start = 0 # 更快速的起点位置faster_end = s_len - 1 # 更快速的终点位置# 优化解法,扔掉s中前面与后面未在t中出现的字符串部分while faster_start < s_len:if t_counter[s[faster_start]] == 0: # s中的该字符未在t中出现,faster_start可以前进faster_start += 1else:break # 找到了第一个出现的位置就跳出,不再前进while faster_end > 0:if t_counter[s[faster_end]] == 0:faster_end -= 1else:break# (2)双指针l, r = faster_start, 0ans_len = 1e9ans = ""while r < faster_end+1:s_r = s[r]if r < s_len and t_counter[s_r] > 0: # r指针未越界,且当前字符在t_counter字频词典中window_counter[s_r] += 1 # 窗口中该字频+1while self.check(window_counter,t_counter) and l <= r: # 在s中找到了包含t的字符串window_len = r-l+1if window_len < ans_len: # 找到了更小的窗口长度ans_len = window_lenans = s[l: l+window_len]s_l = s[l]if t_counter[s_l] > 0: # 只在window_counter中,减去与t串相关的字符词频。window_counter[s_l] -= 1 # 左指针向右移动if window_counter[s_l] == 0: # 有无这行判断对求解无影响,为了严谨del window_counter[s_l]l += 1 # 窗口包含t串,左指针l右移r += 1 # 窗口不包含t串,右指针r右移return ans

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

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

相关文章

05-垃圾收集器ParNewCMS与底层三色标记算法详解

文章目录 垃圾收集算法分代收集理论标记-复制算法标记-清除算法标记-整理算法 垃圾收集器Serial收集器Parallel Scavenge收集器ParNew收集器CMS收集器 CMS的相关核心参数亿级流量电商系统如何优化JVM参数设置(ParNewCMS) 垃圾收集底层算法实现三色标记多标-浮动垃圾漏标-读写屏…

歌曲春节回家:李白的诗意与荆涛的歌声

歌曲春节回家&#xff1a;李白的诗意与荆涛的歌声 “春节回家&#xff0c;春节回家&#xff0c;又是一个春节到&#xff0c;漫天雪花飘。”随着歌手荆涛深情的嗓音&#xff0c;我们仿佛置身于那漫天飞雪的冬日&#xff0c;期待着与家人团聚的温馨时刻。这首歌曲不仅是对春节回…

【Stable Diffusion】在windows环境下部署并使用Stable Diffusion----通过星空整合包一键安装

本专栏主要记录人工智能的应用方面的内容,包括chatGPT、AI绘图等等; 在当今AI的热潮下,不学习AI,就要被AI淘汰;所以欢迎小伙伴加入本专栏和我一起探索AI的应用,通过AI来帮助自己提升生产力; 订阅后可私聊我获取 《从零注册并登录使用ChatGPT》《从零开始使用chatGPT的AP…

数学建模笔记-拟合算法

内容&#xff1a;拟合算法 一.概念&#xff1a; 拟合的结果就是找到一个确定的曲线 二.最小二乘法&#xff1a; 1. 2.最小二乘法的二表示的是平方的那个2 3.求解最小二乘法&#xff1a; 三.评价拟合的好坏 1.总体评分和SST&#xff1a; 2.误差平方和SSE&#xff1a; 3.回…

机器学习:手撕 AlphaGo(一)

图 1-1: AphaGo 结构概览 1. 前言 AlphaGo 是一个非常经典的模型&#xff0c;不论从影响力还是模型设计上。它的技术迭代演进路径&#xff1a;AlphaGo&#xff0c;AlphaGoZero&#xff0c;AlphaZero&#xff0c;MuZero 更是十分精彩。相信有很多同学因为听了 AlphaGo 的故事对…

在Portainer创建Nginx容器并部署Web静态站点实现公网访问

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

Leetcod面试经典150题刷题记录 —— 矩阵篇

矩阵篇 1. 有效的数独2. 螺旋矩阵Python 3. 旋转图像Python额外开辟数组空间原地置换法 4. 矩阵置零5. 生命游戏Python 1. 有效的数独 题目链接&#xff1a;有效的数独 - leetcode 题目描述&#xff1a; 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验…

Android13 Wifi启动流程分析

Android13 Wifi启动流程分析 文章目录 Android13 Wifi启动流程分析一、正常开关wifi 启动流程1、WifiManager2、WifiServiceImpl3、ActiveModeWarden4、ConcreteClientModeManager5、WifiNative6、WifiVendorHal7、HalDeviceManager8、wifi.cpp 二、重启设备时自动开启wifi流程…

centos(linux)安装jenkins

官网&#xff1a;https://pkg.jenkins.io/redhat/ jdk版本要和jenkins对上&#xff01; 安装官网进行操作&#xff1a; sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.reposudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io-…

LeetCode刷题笔记之哈希表

一、字母异位词-判断两个参数内容出现的次数是否相等 滑动窗口、数组排序、计数法、哈希表 1. 242【有效的字母异位词】 题目&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都…

自定义ORM(mybatis)源码(六)-类型处理器

自定义ORM(mybatis)源码(六)-类型处理器 模仿mybatis 用于处理 sql 设置参数类型和 执行 sql 后响应字段的类型处理 TypeHandler public interface TypeHandler<T> {/*** sql 设置参数值* param pstmt* param i* param value* throws SQLException*/void setParamete…

Vue表格中鼠标移入移出input显示隐藏 ,有输入值不再隐藏

Vue表格中鼠标移入移出input显示隐藏 , 不再隐藏的效果 <el-tableref"table":data"tableDatas"borderstyle"width: 100%":span-method"arraySpanMethod"id"table"row-key"id"cell-mouse-enter"editCell&q…

如何把透明OLED显示屏介绍给用户人群

透明OLED显示屏是一种新型的显示技术&#xff0c;它具有透明度高、色彩鲜艳、对比度高、响应速度快等优点。下面是一些介绍透明OLED显示屏的要点&#xff1a; 透明度&#xff1a;透明OLED显示屏的最大特点是其透明度&#xff0c;它可以让光线透过显示屏&#xff0c;使得屏幕背后…

案例101:基于微信小程序的停车共享小程序

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

node实现简单的数据爬虫

前言 我使用的是墨迹天气的页面&#xff0c;因为这个使用的链接简单 页面结构简单并且大都是文字形式 第一步 打开墨迹天气网址 随便点开一个页面 点击F12或者鼠标右键点击检查 查看页面的信息 分析页面内容 使用文字所在的class和标签来定位 编写代码 配置express环境 …

景区气象站:旅游体验的新升级

随着科技的发展和人们生活水平的提高&#xff0c;越来越多的人选择在节假日或周末外出旅游&#xff0c;感受大自然的美好。然而&#xff0c;在享受大自然的同时&#xff0c;天气因素成为了影响旅游体验的关键因素之一。为了更好地服务游客&#xff0c;许多景区开始引入气象站&a…

多层负载均衡实现

1、单节点负载均衡 1&#xff09;站点层与浏览器层之间加入了一个反向代理层&#xff0c;利用高性能的nginx来做反向代理 2&#xff09;nginx将http请求分发给后端多个web-server 优点&#xff1a; 1&#xff09;DNS-server不需要动 2&#xff09;负载均衡&#xff1a;通过ngi…

常用adb命令总结

1.查看设备cpu架构 adb shell getprop ro.product.cpu.abi 2.查看当前屏幕显示的Activity adb shell dumpsys activity activities3.查看apk包详细信息 aapt dump badging ***.apk

Python 中的字符串基础与应用

在Python中&#xff0c;字符串可以用单引号或双引号括起来。‘hello’ 与 “hello” 是相同的。您可以使用print()函数显示字符串文字&#xff1a; 示例&#xff1a; print("Hello") print(Hello)将字符串分配给变量是通过变量名后跟等号和字符串完成的&#xff1a;…

机器视觉算法思路

缺陷检测的一般方法&#xff1a; 1、blob特征 2、blob特征差分 3、频域 4、光度立体 5、测量拟合