滑动窗口算法:双指针高效解题秘籍

一、上期回顾

掌握单调栈 核心逻辑,快速查找左右侧最值元素,搞定每日温度、下一个更大元素等经典题。今天学习滑动窗口,双指针经典算法,解决子数组、子串、区间求和类高频考题。

二、滑动窗口核心概念

滑动窗口 = 左右双指针划定一个连续区间

  • 左指针 left:窗口左边界
  • 右指针 right:窗口右边界
  • 窗口不断向右滑动,动态收缩左边界,满足题意
  • 时间复杂度:O(n),远优于暴力双重循环 O (n²)

两大分类

  1. 固定长度窗口:窗口大小固定,依次滑动统计
  2. 可变长度窗口:窗口大小不固定,求最长 / 最短合法区间

三、固定长度滑动窗口(模板)

适用:定长子数组求和、平均值、最大最小值

复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 求长度为k的子数组最大和
int maxSumFixedWindow(vector<int>& nums, int k)
{
    int sum = 0;
    // 初始化第一个窗口
    for(int i = 0; i < k; i++)
        sum += nums[i];
    int max_val = sum;
    // 滑动窗口
    for(int i = k; i < nums.size(); i++)
    {
        sum = sum - nums[i - k] + nums[i];
        max_val = max(max_val, sum);
    }
    return max_val;
}

int main()
{
    vector<int> arr = {1,3,-1,2,5};
    cout << maxSumFixedWindow(arr,3);
    return 0;
}

四、可变长度滑动窗口(通用核心模板)

通用思路

  1. 右指针不断右移扩大窗口
  2. 窗口不满足条件时,左指针右移缩小窗口
  3. 过程中记录最优答案

模板框架

复制代码
int left = 0;
for(int right = 0; right < n; right++)
{
    // 1. 加入右边界元素,更新窗口状态

    // 2. 窗口不合法,收缩左边界
    while(窗口不满足条件)
    {
        // 移除左边界元素
        left++;
    }

    // 3. 记录最优答案
}

五、经典例题 1:最长无重复子串

复制代码
int lengthOfLongestSubstring(string s)
{
    int cnt[128] = {0};
    int left = 0, res = 0;
    for(int right = 0; right < s.size(); right++)
    {
        char c = s[right];
        cnt[c]++;
        // 出现重复字符,收缩左边界
        while(cnt[c] > 1)
        {
            cnt[s[left]]--;
            left++;
        }
        res = max(res, right - left + 1);
    }
    return res;
}

六、经典例题 2:最小子数组和大于目标值

复制代码
int minSubArrayLen(int target, vector<int>& nums)
{
    int left = 0, sum = 0;
    int res = 1e9;
    for(int right = 0; right < nums.size(); right++)
    {
        sum += nums[right];
        // 满足条件就尽量缩小窗口
        while(sum >= target)
        {
            res = min(res, right - left + 1);
            sum -= nums[left];
            left++;
        }
    }
    return res == 1e9 ? 0 : res;
}

七、滑动窗口使用禁忌

滑动窗口只适用于:区间具有单调性满足:窗口扩张条件变松,窗口收缩条件变紧不适用:元素正负杂乱、无单调规律题型

八、今日核心总结

  1. 滑动窗口依靠左右双指针,线性遍历高效解题
  2. 定长窗口变长窗口两类题型
  3. 右扩左缩,先扩后缩,动态维护合法区间
  4. 字符串子串、数组子数组、区间统计优先用滑动窗口
  5. 核心口诀:右指针无脑走,不合法左指针缩

九、课后练习

  1. 用固定窗口求数组内长度为 2 的最小和
  2. 手写最长无重复子串滑动窗口代码
  3. 自行实现最短子数组满足和大于给定值
相关推荐
fangpin1 天前
GPU编程2: 并行策略
算法
碧海银沙音频科技研究院1 天前
8基于BES2700IHC数字助听器系统开发
嵌入式硬件·算法
HZZD_HZZD1 天前
智能电表选CoAP还是MQTT?合众致达万表实测:CoAP省流17.3%、续航提升38%,附报文拆解与选型矩阵
算法
王老师青少年编程1 天前
2026年全国青少年信息素养大赛算法应用主题赛C++赛项【决赛】模拟卷(汇总)
c++·模拟卷·2026年·青少年信息素养大赛·算法应用主题赛·决赛
linux-hzh1 天前
百日算法修炼 · Day 05
java·算法
paopaokaka_luck1 天前
基于springboot3+vue3的云南本土影视文旅推荐平台(协同过滤算法、Echarts图形化分析)
前端·spring boot·学习·算法·echarts·mybatis
Ivanqhz1 天前
泰勒展开(Taylor Expansion)
算法·决策树·机器学习·集成学习
思麟呀1 天前
C++(八):文件系统库+并行算法
开发语言·c++
凉茶钱1 天前
【数据结构】C语言实现队列
c语言·数据结构
zander2581 天前
34. 在排序数组中查找元素的第一个和最后一个位置:用两个边界定位区间
数据结构·算法·leetcode