滑动窗口Sliding Window

  • 原理
  • 代码设计
  • 基本模块代码实现
  • LeetCode实例(待补充)
  • 3. 无重复字符的最长子串
  • 30. 串联所有单词的子串
  • 76. 最小覆盖子串
  • 159. 至多包含两个不同字符的最长子串
  • 209. 长度最小的子数组
  • 239. 滑动窗口最大值
  • 567. 字符串的排列
  • 632. 最小区间
  • 727. 最小窗口子序列



目前仅为python版本

原理

滑动窗口本质是一个动态的容器,动态指根据需求对其进行扩容或缩容,运动方向为沿着字符串前进或倒退(单向性)。

比如给定一个字符串ABCBADABCD,但滑动窗口的容量扩容到3时,刚好覆盖了ABC三个字符,这时候窗口继续向前滑动,发现B已经在窗口内了,为了让窗口内数据不重复,右移窗口的左指针,使其不再包含B。当窗口遇到D时,D不在窗口内于是为窗口扩容到4,将D包含进窗口[CBAD]

因此滑动窗口本身的时间复杂度为O(n)。

代码设计

通过上述原理我们知道,为了实现动态的滑动窗口。
首先我们必须要有一个容器。
其次我们需要两个指针,左指针用来记录滑动窗口左界限,右指针用来记录滑动窗口右界限。

  • 当容器移动时,左右指针同时增加
  • 当容器扩容时,左指针不会变,右指针增加

再然后个人会倾向于用一个String去记录当前满足题目要求的最长子串,当窗口扩容时将其更新。

基本模块代码实现

n=input()
left = 0  #记录左指针位置
window=[]  #储存当前最长符合题目的子串
curLen=0    #记录滑动窗口的长度大小
maxLen=0    #记录窗口历史最长长度
output=''   #用来记录输出的子串
for i in range(len(n)):
    curLen += 1 #正常向右推进的同时,为了保持窗口坐界限的固定,curLen + 1
    
    #以下部分就要根据题目作出相应调整
    while inValid(n[i]) : #如果新加的元素不满足要求的条件,表明这不是我们目标元素,窗口整体右移
        window.pop(0)   #窗口左界限右移
        curLen -= 1     #缩小窗口容量
        left += 1       #左指针右移
    window.append(n[i])
    
    #这部分可以根据题目调整,比如记录输出的子串
    if curLen > maxLen:
        maxLen = curLen

LeetCode实例(待补充)

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

n=input()
left = 0  
window=[]  
curLen=0    
maxLen=0    
output=''   
for i in range(len(n)):
    curLen += 1 
    
    #以下部分就要根据题目作出相应调整
    while n[i] in window: 
        window.pop(0)   
        curLen -= 1     
        left += 1       
    window.append(n[i])
    
    #这部分可以根据题目调整,比如记录输出的子串
    if curLen > maxLen:
        maxLen = curLen
        output = ''.join(window)
print(maxLen)

30. 串联所有单词的子串

76. 最小覆盖子串

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

209. 长度最小的子数组

239. 滑动窗口最大值

567. 字符串的排列

632. 最小区间

727. 最小窗口子序列