D
AI
学习工作台
8 周后端冲刺2026-05-222 分钟阅读

滑动窗口

固定/可变窗口、最长最短子串与子数组模板

8周冲刺week1滑动窗口子串记笔记标记疑惑

滑动窗口的核心思想

在数组或字符串上维护区间 [left, right],通过 右扩探索、左缩修正 的方式,在线性时间内统计或优化子串/子数组性质。

适用信号词:连续子数组/子串至多/至少 k 个最长/最短和 ≥ target。与 week01-two-pointers 同向指针相似,但窗口强调 区间状态 的增量更新。

固定窗口

窗口长度恒为 k。例如「长度为 k 的子数组最大和」:先算前 k 个和,再滑动——加入 nums[right]、移除 nums[right-k]

def max_sum_subarray(nums, k):
    window = sum(nums[:k])
    best = window
    for right in range(k, len(nums)):
        window += nums[right] - nums[right - k]
        best = max(best, window)
    return best

找所有长度为 k 的子串:右移时同步更新哈希计数,比较是否匹配模式串。

可变窗口

最长无重复子串

last[ch] 记录字符上次出现下标;若重复且位置 ≥ left,则 left = last[ch] + 1

def length_of_longest_substring(s):
    last = {}
    left = ans = 0
    for right, ch in enumerate(s):
        if ch in last and last[ch] >= left:
            left = last[ch] + 1
        last[ch] = right
        ans = max(ans, right - left + 1)
    return ans

和 ≥ target 的最短子数组

右扩累加 total,当 total >= target 时不断左缩并更新最小长度。

def min_subarray_len(target, nums):
    left = total = 0
    ans = float("inf")
    for right, x in enumerate(nums):
        total += x
        while total >= target:
            ans = min(ans, right - left + 1)
            total -= nums[left]
            left += 1
    return 0 if ans == float("inf") else ans

至多 K 个不同字符的最长子串

右扩增加种类数;当种类 > K 时左缩直到 ≤ K,更新最长长度。

窗口状态设计

| 题目类型 | 维护量 | 左缩条件 | |----------|--------|----------| | 无重复 | 字符最后位置 | 出现重复 | | 异位词 | 26 计数差 | 窗口满且匹配 | | 和/积约束 | total / product | 违反不等式 |

乘积 < k 类题:右扩乘积,超限时左除;注意零的处理(归零后重新开窗)。

常见陷阱

  • 空串/全正数:最短子数组若不存在返回 0。
  • 更新答案时机:最长在扩张时更新;最短在满足条件的收缩时更新。
  • 字符集:大小写是否区分、是否含空格。
  • 与哈希结合

    「连续子数组和为 k」用前缀和 + 哈希计数;滑动窗口则用于 正整数和 ≥ target 等单调场景。分清何时用前缀和(允许负数)、何时用窗口(正数单调)。

    配合 week01-hash-table 与站内算法章节,建议刷:无重复子串、最小覆盖子串、水果成篮(至多两种类型)三类模板题各一道。

    实战巩固与面试表达

    本篇属于 8 周冲刺 week01-sliding-window 主题。复习时先闭卷回答 frontmatter 中三张 flashcard,再展开口述两个「为什么」:为什么这种方案能 work、边界失败时如何降级。与相邻章节对照:算法篇强调复杂度与模板,Go 篇强调工程默认写法,中间件篇强调线上故障案例。

    动手与自检清单

    用 25 分钟限时做 1 道相关练习题或画出一张架构/数据结构示意图;用 5 分钟写 STAR 片段说明你在项目里是否用过类似技术。记录 3 个面试追问及你的标准答法,存入 /zh/notebook/master-plan 笔记。若某点不熟,回到对应 /chapters 交互 Lab 重新走一遍流程,比死记卡片更有效。

    易错点提醒

    避免只背名词不会画图;避免只说优点不谈 trade-off(性能、一致性、运维成本至少提一项);避免把学习 Demo 说成百万 QPS 生产。回答时使用「场景 → 方案 → 结果 → 反思」四段式,体现工程成熟度。

    知识卡片

    问题

    固定长度 k 的窗口如何移动?

    点击翻转查看答案

    答案

    右指针每步 +1 加入新元素;当窗口长度超过 k 时左指针 +1 移出最左元素;长度始终为 k 时更新答案。

    问题

    可变窗口求「最短满足条件」的套路?

    点击翻转查看答案

    答案

    右扩直到满足条件,然后不断左缩直到不满足,每次满足时更新最小长度;右指针只增,左指针只增,总 O(n)。

    问题

    窗口内字符计数用什么结构?

    点击翻转查看答案

    答案

    ASCII 用长度 128/256 数组;Unicode 或键稀疏用哈希表;维护「种类数」「最大值」「和」等视题目而定。