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;
    }
相关推荐
D e re k ZH3 分钟前
C++ 并发、未定义行为与工程化难点(No 3)
数据结构·c++·算法·面试
释厄6231 小时前
同性线套娃律——圆面积必然=1+2+...+n 的求和·圆心不与 π 相关
java·人工智能·算法·1024程序员节
暴力求解1 小时前
C++ ---继承(二)
开发语言·c++·算法
码林拾遗WJ1 小时前
告警分级的自动化实测:模型判断 vs 人工拍板
人工智能·算法·自动化
Tisfy2 小时前
LeetCode 0453.最小操作次数使数组元素相等:两次遍历(反向思维)
算法·leetcode·题解·遍历·反向思维
君万2 小时前
【LeetCode每日一题】回溯:46. 全排列 78. 子集 39. 组合总和
算法·leetcode·go
Keep_Trying_Go3 小时前
Consistent-Point半监督人群计数算法详解
人工智能·深度学习·算法·计算机视觉·人群计数
在所不辞兄3 小时前
【零基础学智能仿真-69】综合项目——材料参数驱动的仿真研究
人工智能·深度学习·神经网络·算法·机器学习·1024程序员节
Tisfy4 小时前
LeetCode 3665.统计镜子反射路径数目:三个动态规划数组
leetcode·动态规划·代理模式·题解
怕浪猫4 小时前
Super-agent 在各大模型厂商的应用情况
算法·面试·github