什么是滑动窗口?

其实就是一个队列,比如题中的 abcabcbb找出其中不含有重复字符的 最长子串 的长度,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?我们只要把队列的左边的元素移出就行了,直到满足题目要求!一直维持这样的队列,找出队列出现最长的长度时候,求出解!
;

模板

class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:import collectionsres =[]need = collections.Counter(p)window = collections.Counter()valid , left , right = 0 , 0 , 0while right < len(s):c = s[right]right += 1#进行窗口内数据的一系列更新,代码就需要改这里if need[c]:window[c] += 1if window[c] == need[c]:valid += 1#判断左侧窗口是否收缩while right - left >= len(p):# 当窗口符合条件时,把起始索引加入 resif valid == len(need):res.append(left)d = s[left]left += 1#进行窗口内数据的一系列更新,代码就需要改这里if need[d]:if window[d] == need[d]:valid -= 1window[d] -= 1return res

滑动窗口中用到了左右两个指针,它们移动的思路是:以右指针作为驱动,拖着左指针向前走。右指针每次只移动一步,而左指针在内部 while 循环中每次可能移动多步。右指针是主动前移,探索未知的新区域;左指针是被迫移动,负责寻找满足题意的区间。

初始化窗口端点L,R,一般L为0,R为1初始化最优值while R < len(Array):while R < len(Array):R += 1              #移动右端点if R < len(Array):更新状态        if 状态满足条件:可选的更新最优值的位置break           #一旦满足条件即跳出if R == len(Array):     # 若循环是由于移动到数组末尾结束,则停止整个程序。因为之后已经不再有可能的解breakwhile L < R:更新状态    # 移动左端点,需要更新状态L += 1if 状态满足条件:可选的更新最优值的位置else:  # 一旦窗口所在区间不再满足条件即跳出,去移动右端点break可选的对于L,R端点的后续处理return 最优值

LeetCode-3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。示例 1:输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
class Solution:def lengthOfLongestSubstring(self, s):""":type s: str:rtype: int"""from collections import defaultdictlookup = defaultdict(int)start = 0           # 记录当前子串的初始位置end = 0             # end自增遍历一遍整个字符串max_len = 0         # 之前无重复最长子串counter = 0         # 窗口移动标志while end < len(s):if lookup[s[end]] > 0:      # 有重复过的就进入循环counter += 1lookup[s[end]] += 1end += 1while counter > 0:          # 窗口移动if lookup[s[start]] > 1:# 是否是窗口最左边的字符重复:是的话只移动一次,不是的话一直移动直到重复字符在最左边counter -= 1lookup[s[start]] -= 1start += 1max_len = max(max_len, end - start)return max_len
class Solution(object):def lengthOfLongestSubstring(self, s):""":type s: str:rtype: int"""L, R = 0, -1optim = 0status = set()while R < len(s):while R < len(s):R += 1if R == len(s):breakif s[R] not in status:status.add(s[R])optim = max(optim, R - L + 1)else:breakif R == len(s):breakwhile L < R:if s[L] != s[R]:status.remove(s[L])L += 1else:L += 1breakreturn optim

LeetCode-76. 最小覆盖子串

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:

如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

class Solution:def minWindow(self, s: 'str', t: 'str') -> 'str':from collections import defaultdictlookup = defaultdict(int)for c in t:lookup[c] += 1start = 0end = 0min_len = float("inf")  # 无穷大counter = len(t)        # counter为0时,开始窗口移动res = ""while end < len(s):if lookup[s[end]] > 0:  # 可行窗口中出现一次t中字符就就记录一次counter -= 1      lookup[s[end]] -= 1end += 1while counter == 0:         # 移动窗口if min_len > end - start:min_len = end - startres = s[start:end]if lookup[s[start]] == 0:   # 行为窗口中最左的字符是t中字符并且只在行为窗口中出现一次就停止移动counter += 1lookup[s[start]] += 1start += 1return resn = Solution()
nn = n.minWindow('ABAACBAB', 'ABC')
print(nn)

159. 至多包含两个不同字符的最长子串

class Solution:def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int:from collections import defaultdictlookup = defaultdict(int)start = 0end = 0max_len = 0counter = 0while end < len(s):if lookup[s[end]] == 0:counter += 1lookup[s[end]] += 1end +=1while counter > 2:if lookup[s[start]] == 1:counter -= 1lookup[s[start]] -= 1start += 1max_len = max(max_len, end - start)return max_len

340. 至多包含 K 个不同字符的最长子串

class Solution:def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:from collections import defaultdictlookup = defaultdict(int)start = 0end = 0max_len = 0counter = 0while end < len(s):if lookup[s[end]] == 0:counter += 1lookup[s[end]] += 1end += 1while counter > k:if lookup[s[start]] == 1:counter -= 1lookup[s[start]] -= 1start += 1max_len = max(max_len, end - start)return max_len

LeetCode-30. 串联所有单词的子串

class Solution:def findSubstring(self, s, words):from collections import Counterif not s or not words:return []one_word = len(words[0])word_num = len(words)n = len(s)if n < one_word: return []words = Counter(words)res = []for i in range(0, one_word):        # 防止单词截断的问题cur_cnt = 0         # 窗口中每出现一次单词就加一,非words中单词减一left = i            # 窗口左指针right = i           # 窗口右指针cur_Counter = Counter()         # 创建窗口while right + one_word <= n:    # 窗口右指针移动遍历sw = s[right:right + one_word]right += one_word# cur_Counter[w] += 1# cur_cnt += 1if w not in words:left = rightcur_Counter.clear()cur_cnt = 0else:cur_Counter[w] += 1cur_cnt += 1while cur_Counter[w] > words[w]:# 窗口中出现非words中单词或者words中单词出现1次以上,需移动窗口左指针,移动到w的位置left_w = s[left:left+one_word]left += one_wordcur_Counter[left_w] -= 1cur_cnt -= 1if cur_cnt == word_num :    # words中单词已在窗口中全部出现res.append(left)return resn = Solution()
nn = n.findSubstring("barfoothefoobarman", ["foo","bar"])
print(nn)

LeetCode-209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。示例: 输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
class Solution:def minSubArrayLen(self, s, nums):if sum(nums) < s:return 0if sum(nums) == s:return len(nums)left = 0right = 0sub_sum = 0length = len(nums)for right, item in enumerate(nums):sub_sum += itemwhile sub_sum >= s:length = min(length, right-left+1)sub_sum -= nums[left]left += 1return length
class Solution:def minSubArrayLen(self, s, nums):summation = 0L, R = 0, -1optim = len(nums) + 1while R < len(nums):while R < len(nums):R += 1if R < len(nums):summation += nums[R]if summation >= s:optim = min(optim, R - L + 1)breakif R == len(nums):breakwhile L < R:summation -= nums[L]L += 1if summation >= s:optim = min(optim, R - L + 1)else:breakreturn optim if optim != len(nums) + 1 else 0

Leetcode 1004. 最大连续1的个数 III

给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。
返回仅包含 1 的最长(连续)子数组的长度。示例 1:输入:A = [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:输入:A = [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。
def longestOnes(A: List[int], K: int) -> int:L, R = 0, -1optim = 0while R < len(A):while R < len(A):R += 1if R == len(A):breakif A[R] == 0:K -= 1if K < 0:   #第一次不满足条件breakelse:   #满足条件时更新最优值optim = max(optim, R - L + 1)if R == len(A):breakwhile L < R:if A[L] == 0:K += 1L += 1if K >= 0:breakreturn optim

滑动窗口问题

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

30. 串联所有单词的子串

76. 最小覆盖子串

159. 至多包含两个不同字符的最长子串

209. 长度最小的子数组

239. 滑动窗口最大值

567. 字符串的排列

632. 最小区间

727. 最小窗口子序列

LeetCode Hot100 ---- 滑动窗口专题相关推荐

  1. Leetcode双指针滑动窗口相关题目

    滑动窗口 滑动窗口解决哪种问题? 滑动窗口解决给定两个字符串S和T,问你S中是否存在一个子串,包含T中的所有字符并且不含有其他字符. 窗口右指针向右移动,窗口增大,直到满足条件,这时候找到可行解. 窗 ...

  2. LeetCode 480. 滑动窗口中位数(大小堆升级版+set实现)

    1. 题目 中位数是有序序列最中间的那个数. 如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) ...

  3. LeetCode 239. 滑动窗口最大值(双端队列+单调栈)

    文章目录 1. 题目信息 2. 解题 2.1 暴力法 2.2 双端队列法 1. 题目信息 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内 ...

  4. LeetCode 239:滑动窗口最大值 思考分析

    给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 进阶: 你能在线性 ...

  5. leetcode 480. 滑动窗口中位数(堆+滑动窗口)

    中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) / 2 = 2 ...

  6. leetcode 239. 滑动窗口最大值(单调队列)

    给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示例 1: 输 ...

  7. 2022-3-26 Leetcode 239.滑动窗口最大值

    class Solution {public int[] maxSlidingWindow(int[] nums, int k) {if(nums == null || nums.length < ...

  8. LeetCode Hot100 ---- 二分查找专题

    什么是二分查找 二分查找是计算机科学中最基本.最有用的算法之一. 它描述了在有序集合中搜索特定值的过程. 二分查找中使用的术语: 目标 Target -- 你要查找的值 索引 Index -- 你要查 ...

  9. LeetCode Hot100 ---- 回溯算法专题

    回溯算法是什么?解决回溯算法相关的问题有什么技巧?如何学习回溯算法?回溯算法代码是否有规律可循? 其实回溯算法其实就是我们常说的 DFS 算法,本质上就是一种暴力穷举算法. 解决一个回溯问题,实际上就 ...

最新文章

  1. ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法
  2. ExecuteScalar()如何返回整数
  3. 安卓java修改按钮大小_android弹出activity设置大小的方法
  4. Cissp-【第2章 资产安全】-2021-1-14(163页-185页)
  5. 设计模式:访问者模式(Visitor Pattern)
  6. MATLAB 基本数据类型和调用方式
  7. 【AI学院】老司机手把手带学言有三的经典书籍《深度学习之图像识别》,需要的赶紧上车吧...
  8. c malloc 头文件_C 数据类型
  9. Web前端行业的机遇与自我规划,如果你对未来没有方向 不如看一看,或许就是一道曙光!
  10. 如何解决回归任务数据不均衡的问题?
  11. [codeforces538F]A Heap of Heaps
  12. C++ Web编程实战
  13. matlab tabular,LaTeX表格tabular背景色添加技巧
  14. 【数据结构】约瑟夫问题
  15. 平安京服务器维护,决战平安京无法登陆怎么解决 无法登陆原因及解决方案一览...
  16. 光速掌握史上最全--计算机数制转换
  17. [java基础入门]java期末常考题。定义一个父类person,该类中有两个私有的属性姓名name和age,实现两个属性的封装 定义构造等等来初始化成员变量name和age,在定义显示show方法将
  18. 布局5G旗舰移动市场 MediaTek发布天玑新品
  19. 迎国庆,九月复盘你搞了多少钱?
  20. 测试开发3年,我决定去读个名校硕士

热门文章

  1. IOS , plist 配置项说明
  2. NSFileHandle
  3. python spark视频_Spark2.x+Python大数据机器学习视频课程
  4. Vue.js入门教程-组件注册
  5. 华三云:不做开源的投机者
  6. docker 常用命令(1)
  7. 实战 SSH 端口转发
  8. django学习笔记之forloop
  9. 【2014年计划】工作,学习两不误
  10. 韩顺平 Mysql数据库优化(一) 优化概述