滑动窗口模板

一句话说明

滑动窗口是双指针的一种应用,通过维护一个窗口来优化子串/子数组问题。

💻 模板代码

适用场景

窗口类型适用场景特点
固定窗口长度固定的子数组简单,直接滑动
最长窗口最长无重复、最长满足条件扩大为主,违规时收缩
最短窗口最小覆盖、最短满足条件满足时收缩,求最小
计数窗口统计子串/子数组数量利用”最多k个”的性质

💡 解题步骤

  1. 初始化:left = 0, window = {}, result
  2. 扩大窗口:right右移,更新window
  3. 收缩窗口:while条件满足时,left右移
  4. 更新结果:在合适的时机更新答案

🎯 经典题目

题目LeetCode窗口类型
无重复字符的最长子串3最长窗口
最小覆盖子串76最短窗口
字符串的排列567固定目标
找到字符串中所有字母异位词438固定目标
长度最小的子数组209最短窗口

Go 代码

// 无重复字符的最长子串
func lengthOfLongestSubstring(s string) int {
    left := 0
    window := make(map[byte]int)
    maxLen := 0
 
    for right := 0; right < len(s); right++ {
        c := s[right]
        window[c]++
 
        for window[c] > 1 {
            d := s[left]
            window[d]--
            left++
        }
 
        if right-left+1 > maxLen {
            maxLen = right - left + 1
        }
    }
 
    return maxLen
}
 
// 最小覆盖子串
func minWindow(s string, t string) string {
    if len(s) == 0 || len(t) == 0 {
        return ""
    }
 
    need := make(map[byte]int)
    for i := 0; i < len(t); i++ {
        need[t[i]]++
    }
 
    window := make(map[byte]int)
    left, valid := 0, 0
    minLen, start := len(s)+1, 0
 
    for right := 0; right < len(s); right++ {
        c := s[right]
 
        if _, ok := need[c]; ok {
            window[c]++
            if window[c] == need[c] {
                valid++
            }
        }
 
        for valid == len(need) {
            if right-left+1 < minLen {
                minLen = right - left + 1
                start = left
            }
 
            d := s[left]
            left++
 
            if _, ok := need[d]; ok {
                if window[d] == need[d] {
                    valid--
                }
                window[d]--
            }
        }
    }
 
    if minLen == len(s)+1 {
        return ""
    }
    return s[start : start+minLen]
}

返回:算法模板