我的测试学习站TEST LEARNING HUB
开始学习
首页/精华文章/6. 滑动窗口题怎么入门

6. 滑动窗口题怎么入门

滑动窗口是数组和字符串题中的常见技巧。它本质上是用左右边界维护一个连续区间,根据条件扩大或收缩窗口。测试岗手撕代码中,滑动窗口通常考入门题,比如最长无重复子串、固定长度子数组最大和、最小长度子数组等。它比普通遍历稍难,但掌握模板后并不复杂。

滑动窗口特别适合解决“连续子串”“连续子数组”“最长”“最短”“满足条件的区间”这类问题。看到这些关键词,就可以考虑滑动窗口。

一、什么是滑动窗口

窗口就是数组或字符串中的一段连续区间。

例如字符串 abcabcbb 中,abc、bca 都是窗口。

滑动窗口通常有两个指针:

  • left:窗口左边界;
  • right:窗口右边界。

right 向右扩展窗口,left 根据条件收缩窗口。

二、固定窗口

固定窗口长度不变,适合固定长度子数组问题。

例如求长度为 k 的子数组最大和:

def max_sum(nums, k):
    if len(nums) < k:
        return None
    window_sum = sum(nums[:k])
    max_value = window_sum
    for i in range(k, len(nums)):
        window_sum += nums[i] - nums[i - k]
        max_value = max(max_value, window_sum)
    return max_value

每次右边进一个,左边出一个。

三、可变窗口

可变窗口长度会变化,适合最长或最短满足条件的问题。

经典题:最长无重复子串。

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

这里窗口始终保持无重复字符。

四、滑动窗口通用思路

可以按这个模板思考:

定义 left/right -> 扩大 right -> 更新窗口状态 -> 判断是否满足条件 -> 收缩 left -> 更新答案

关键是窗口内维护什么信息:

  • 当前和;
  • 字符出现次数;
  • 当前最大长度;
  • 是否有重复;
  • 是否满足目标值。

五、最小长度子数组

题目:找和大于等于 target 的最短连续子数组长度。

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

这里 right 扩大窗口,满足条件后 left 收缩,寻找更短答案。

六、滑动窗口和双指针关系

滑动窗口可以看作同向双指针的一种。两个指针都向右移动,维护一个连续区间。

区别是滑动窗口通常会维护窗口状态,比如计数、总和、集合等。

七、常见错误

1. 不知道什么时候移动 left

移动 left 的条件由题目决定,比如有重复、总和超过目标、窗口长度超过 k。

2. 忘记更新窗口状态

left 移动时要把离开窗口的元素从计数或总和中移除。

3. 答案更新位置错误

最长题通常在窗口合法时更新;最短题通常在满足条件后收缩时更新。

4. 边界未处理

空字符串、数组长度小于 k、目标不存在都要处理。

八、测试用例怎么补

滑动窗口题要测:

  • 空输入;
  • 单元素;
  • 全部重复;
  • 全部不重复;
  • 窗口在开头;
  • 窗口在结尾;
  • 不存在满足条件;
  • k 大于数组长度。

九、面试回答模板

如果面试官问“滑动窗口题怎么入门”,可以这样回答:

滑动窗口适合解决连续子数组或子串问题,尤其是最长、最短、固定长度这类题。核心是用 left 和 right 维护一个窗口,right 负责扩大窗口,left 根据条件收缩窗口,同时维护窗口内的状态,比如字符计数或当前和。固定窗口如长度为 k 的子数组最大和,每次右边进一个左边出一个;可变窗口如最长无重复子串,需要用 Map 记录字符位置,遇到重复就移动 left。写完后要测空输入、全重复、无重复和不存在满足条件的场景。

十、练习清单

  1. 固定长度最大和;
  2. 最长无重复子串;
  3. 最小长度子数组;
  4. 字符串中是否包含排列;
  5. 最大连续 1 个数;
  6. 长度为 k 的平均值;
  7. 重复字符窗口收缩;
  8. 手写窗口模板;
  9. 总结 left 移动条件;
  10. 准备滑动窗口表达。

滑动窗口入门的关键是把窗口状态说清楚。只要知道窗口里维护什么、什么时候扩、什么时候缩,就能写出大多数基础题。

配套刷题: