一,今日学习任务
第 3 天 滑动窗口算法 209. 长度最小的子数组
题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建 议大家先看视频讲解。
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
二,初次解题思路和思考
刚拿到这道题,第一反应就是最直白的暴力解法:
用两层for循环,枚举所有可能的子数组起点和终点,计算子数组的和,找到满足和≥target的最小长度。
这种方法逻辑简单,写起来没难度,但时间复杂度高达O(n²),数组稍大就会超时,完全不是最优解。
再仔细想,题目要求在原数组上操作,不能用额外空间,还得高效,那肯定就是用滑动窗口法了。
滑动窗口的核心就是用两个指针维护一个窗口,一次遍历就完成所有计算,直接把时间复杂度从O(n²)降到O(n),完美符合要求。
三,写代码时核心注意点
我最容易搞混的就是窗口的移动逻辑和边界条件,总结了几个关键要点:
1. 两个指针到底干嘛用?
◦ 左指针:窗口的左边界,代表当前窗口的起始位置
◦ 右指针:窗口的右边界,用来扩张窗口,遍历整个数组
◦ sum变量:记录当前窗口内所有元素的和
2. 什么时候移动指针?
◦ 右指针一直往后走,不断把元素加入窗口,扩张窗口
◦ 当窗口内的和sum ≥ target时,尝试收缩左边界(左指针右移),直到sum < target,同时记录过程中的最小长度
◦ 核心逻辑:窗口只向右移动,不回退,保证了O(n)的时间复杂度
3. 暴力法的坑
◦ 暴力法中两层循环的边界很容易写错,而且对于大数组会直接超时,只能作为理解题意的基础写法
◦ 容易忽略子数组长度的初始值设置,导致结果错误
四,操作
测试示例
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2,解释:子数组 [4,3] 是该条件下长度最小的子数组
输入:target = 4, nums = [1,4,4]
输出:1,解释:子数组 [4] 满足和为4,长度最小
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0,解释:没有满足条件的子数组
五,今天收获
1. 滑动窗口是解决「连续子数组」问题的核心技巧,能大幅优化时间复杂度,必须吃透
2. 暴力法适合练手,但面试一定要用滑动窗口,体现算法思维
3. 滑动窗口的核心是窗口只向右移动,左指针不会回退,这是O(n)时间复杂度的关键
4. 遇到「连续子数组求和」「最小/最大长度子数组」这类问题,第一反应就该想到滑动窗口
5. 处理边界条件时,一定要注意初始值的设置(比如result初始为INT_MAX),避免结果错误