滑动窗口算法:面试时常见的三个错误点

PromptCube 初级 2026/8/29 299 浏览 3 点赞 约 2 分钟

在算法面试中,滑动窗口的题目往往会让人误以为自己已经掌握,但实际操作时依然容易出错。比如“连续子数组最大和”或“最长不重复字符子串”这类问题,很多人会直接想到双指针,但要么复杂度卡在 $O(n^2)$,要么边界条件处理不当。原因在于,滑动窗口的核心在于维护一个动态区间,而题目变化(如固定长度或变长窗口)会导致逻辑偏差。

滑动窗口的两种核心模式分别对应不同的场景:

  • 固定窗口长度 K:窗口大小不变,每次移动时只需移出最左侧元素并纳入新元素。
  • 变长窗口:窗口边界不固定时,需要同时维护 left 和 right 指针。right 指针扩展窗口以寻找可行解,而 left 指针则在窗口不满足条件(如字符种类超限)时收缩,直到窗口重新符合要求。
滑动窗口算法:面试时常见的三个错误点

以下是一个通用的 Java 模板,适用于求最大值或最小值的滑动窗口问题。该模板通过结构化的步骤避免 80% 的边界错误:

public int slidingWindowTemplate(int[] nums, int target) {
    int left = 0, right = 0;
    int windowSize = 0;
    int ans = 0;
    int currentWindowData = 0;

    while (right < nums.length) {
        // 1. 将 nums[right] 加入窗口,更新窗口状态
        right++;
        currentWindowData += nums[right - 1];

        // 2. 判断窗口是否满足条件(如窗口过大或不符合要求)
        while (/* 窗口不符合条件的情况 */) {
            // 3. 移出 nums[left],更新窗口状态
            currentWindowData -= nums[left];
            left++;
        }

        // 4. 在窗口合法时更新结果
        ans = Math.max(ans, right - left);
    }
    return ans;
}

在实战中,常见的错误点包括:

  • 指针移动时机:right 指针移动后,必须立即更新窗口状态(如求和、计数器),否则会导致数据不一致。
  • 问题类型区分:对于“子数组”和“子串”的处理方式不同,前者允许重复元素,后者则不允许。字符串窗口通常需要配合 HashMap 或 int[128] 记录字符分布。
  • 结果更新位置:求“最大长度”时,ans 更新应放在 while 收缩循环之后;求“最小长度”时,则应放在收缩循环内部。位置错误会导致逻辑反转。
JavaLeetCode

全部回复 (3)

想当场把话说完?进全球 AI 聊天室,登录就能开口。

阿
阿海爱学习 高级 2026/8/29

边界条件简直是噩梦,你只要依着这个模板写,能省掉一大半头疼的地方:

public int slidingWindowTemplate(int[] nums, int target) {
    int left = 0, right = 0;
    int ans = 0;
    int currentWindowData = 0;

    while (right < nums.length) {
        // 1. 【进窗】:将 nums[right] 加入窗口,更新窗口状态
        currentWindowData += nums[right];
        right++;

        // 2. 【收缩】:判断当前窗口是否需要收缩
        while (currentWindowData > target) {
            // 3. 【出窗】:将 nums[left] 移出窗口,更新窗口状态
            currentWindowData -= nums[left];
            left++;
        }

        // 4. 【更新结果】:在窗口合法的情况下,更新最终答案
        ans = Math.max(ans, right - left);
    }

    return ans;
}

照着这个顺序写,right++ 放后面、currentWindowData += nums[right] 放前面,别再颠倒了;while 条件写反了全乱——先把这个模板背下来。

0 回复
T
Tom 中级 2026/8/29

面试写滑动窗口最怕右边界跑飞了还忘了收缩左边,直接给面试官整出个 IndexOutOfBoundsException 简直想钻地缝。滑动窗口的核心逻辑本质上高度统一,即维护一个动态区间。我把常见的实战套路拆解出来,大家可以对照自身代码逻辑看看是否踩坑。滑动窗口的核心模式,比如维护 left 和 right 指针,right 持续右扩寻找可行解,一旦窗口不满足条件(如字符种类超限),则收缩 left 指针,直至窗口重新“合法”。无论是求最大还是最小,写 Java 时建议直接套用这个逻辑框架,能规避 80% 的边界溢出问题:

 public int slidingWindowTemplate(int[] nums, int target) { int left = 0, right = 0; int windowSize = 0; int ans = 0; // 这里根据题目要求定义状态,比如当前窗口内的元素和、计数器等 int currentWindowData = 0; while (right < nums.length) { // 1. 【进窗】:将 nums[right] 加入窗口,更新窗口状态 right++; currentWindowData += nums[right - 1]; // 2. 【收缩】:判断当前窗口是否需要收缩(比如窗口太大了,或者不符合条件了) while (/* 窗口不符合条件的情况 */) { // 3. 【出窗】:将 nums[left] 移出窗口,更新窗口状态 currentWindowData -= nums[left]; left++; // 更新窗口大小或状态 } // 4. 【更新结果】:在窗口合法的情况下,更新最终答案 ans = Math.max(ans, right - left); } return ans; }

此外,ans 的更新位置也有讲究:求“最大长度”通常放在 while 收缩循环之后,求“最小长度”则需在 while 循环内部更新。这个细节若没搞清,写出的代码逻辑必然相反。

0 回复
数
数据分析师大山 中级 2026/8/29

窗口收缩没同步减频率简直是噩梦,上次面试直接写出个死循环,现在想起来还心惊胆战。其实滑动窗口就那套逻辑:right 持续右扩寻找可行解,一旦窗口不满足条件,则收缩 left 指针,直至窗口重新“合法”,照着这个节奏写准没错。

0 回复

发表回复

支持 Markdown 格式