LeetCode刷题滑动窗口(长度最小的子数组)

滑动窗口的相关知识

一、什么是滑动窗口?

滑动窗口 = 双指针 + 维护一个连续区间。

通过 left 和 right 两个指针维护一个窗口,避免重复计算。

  • right++:扩大窗口,加入新元素。

  • left++:缩小窗口,移除旧元素。

  • sum:记录窗口内元素之和。

二、什么时候使用?

一般满足以下特点:

  1. 连续性:题目要求连续子数组、子串。

  2. 区间性质:需要维护区间的和、长度、字符数量等。

  3. 单调性:窗口扩大或缩小时,能够判断应该移动哪个指针。

常见题型:长度最小的子数组、最长无重复子串、固定长度子数组最大和。

三、怎么用

主要以第一道题来演示

进窗口 → 判断 → 更新结果 → 出窗口

四、为什么滑动窗口是对的?

核心在于 利用单调性,排除不可能的答案。

以正整数数组、寻找和大于等于 target 的最短子数组为例:

  • sum < target:窗口不满足条件,只能扩大窗口。

  • sum >= target:窗口满足条件,记录长度,再尝试缩小窗口。

  • 每次缩小时,已经记录当前答案,因此不会遗漏最优解。

因为数组元素都是正数,扩大窗口只会让和增加,缩小窗口只会让和减少,所以不需要反复回头检查。

五、最后总结

滑动窗口的本质:通过维护连续区间,利用单调性减少重复遍历。

  • 暴力枚举:通常 \(O(n^2)\)

  • 滑动窗口:典型双指针写法 \(O(n)\)

一,长度最小的子数组

解题思路:

首先让 left 和 right 都指向数组开头,通过 right++ 不断扩大窗口,并累加窗口内的元素。当 sum >= target 时,说明当前窗口满足条件,此时更新最短长度,再通过 left++ 缩小窗口,尝试寻找更短的子数组。直到 sum < target,再继续移动 right。整个过程中两个指针都不需要回退,最终得到最短长度 2

代码演示:

java 复制代码
    public static int minSubArrayLen(int target, int[] nums) {
        int left=0,sum=0,len=Integer.MAX_VALUE;

        for (int right = 0; right < nums.length; right++) {
            sum+=nums[right];
            while (sum>=target){
                //更新len
                len=Math.min(len,right-left+1);
                sum-=nums[left++];
            }
        }
        return len == Integer.MAX_VALUE ?0 : len;
    }

二,无重复字符串的最长字串

解题思路:

首先让 left 和 right 都指向字符串开头,利用哈希表记录窗口内的字符。通过 right++ 不断扩大窗口,如果新字符没有重复,就加入哈希表并更新最长长度;如果出现重复,就通过 left++ 不断移除左侧字符,直到重复消失。因为之前经过的区间已经判断过,所以两个指针都不需要回退,最终得到最长长度 3

代码演示:

java 复制代码
    public static int lengthOfLongestSubstring(String s) {
        int left=0,len=0;
        // 哈希表记录窗口内的字符
        Set<Character> set = new HashSet<>();
        for (int right = 0; right < s.length(); right++) {
            char ch=s.charAt(right);
            while (set.contains(ch)){
                //因为哈希表是记录的当前left与right组成的滑块里面的字符,然后判断是否有重复的,所以我们删除是要从当前窗口的开始一直删除到重复的那一个
                set.remove(s.charAt(left));
                left++;
            }
            set.add(ch);
            len=Math.max(len,right-left+1);
        }
        return len;
    }
相关推荐
@atweiwei1 小时前
训练 AI 大模型系列之 LoRA:不动模型本体,靠一条低秩旁路改专长(附完整手算算例)
人工智能·算法·ai·语言模型·rag
救救孩子把1 小时前
AI面试八股文-01_1-LLM基础概念(Token-上下文窗口-幻觉)
人工智能·面试·职场和发展·llm·token
yi0111 小时前
DAY27: LeetCode 110. 平衡二叉树 | 在递归中判断是否平衡
人工智能·笔记·python·算法·leetcode·二叉树·递归
9624561 小时前
餐饮 SaaS 优惠券系统架构演进(七)营销定价引擎设计:活动、会员价、优惠券、买赠如何在同一 PriceQuote 中可解释地组合
java·运维·算法
xuxigifxfh2 小时前
牛客:HJ21 简单密码
java·开发语言·算法
qq_408606862 小时前
确界的倒数性质证明
学习·算法
小蒋观天下2 小时前
【安防AI工程实战二】AI摄像头帧率抖动根治:ISP曝光时序与AI推理时序冲突深度定位
人工智能·深度学习·算法·安全·机器学习·ai大模型
云和数据.ChenGuang2 小时前
trace 是RAG检索链路的**全链路追踪日志对象
人工智能·深度学习·算法·排序算法
Evand J2 小时前
【PMSM例程6】永磁同步电机(PMSM)基于增广EKF的d-q轴电感分阶段辨识算法|电机参数估计与误差分析
算法·matlab·电机·ekf