【Day 8】公开打卡第8天 | LeetCode 209. 长度最小的子数组(滑动窗口) + 可变窗口模板

5 阅读2分钟
  1. LeetCode 部分

    • 题目链接:leetcode.cn/problems/mi…
    • 难度:中等
    • 时间复杂度:O(n)(每个元素最多进出窗口一次)
    • 空间复杂度:O(1)
    • 核心思路(简短): 使用滑动窗口(左、右指针),不断扩大右指针累加和。当窗口和 ≥ target 时,尝试缩小左指针,更新最小长度。窗口始终保持“和 ≥ target”的最小可能。
    • 代码(Go 版本,标准滑动窗口写法):

Go

func minSubArrayLen(target int, nums []int) int {
    n := len(nums)
    if n == 0 {
        return 0
    }
    
    left := 0
    sum := 0
    minLen := n + 1  // 初始化为不可能的大值
    
    for right := 0; right < n; right++ {
        sum += nums[right]  // 扩大窗口
        
        // 窗口和满足条件时,尽量缩小左边界
        for sum >= target && left <= right {
            minLen = min(minLen, right-left+1)
            sum -= nums[left]  // 缩小窗口
            left++
        }
    }
    
    if minLen == n+1 {
        return 0
    }
    return minLen
}

// 辅助函数
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}
  • C++ 版本(如果你想双语放一个简洁版):

C++

int minSubArrayLen(int target, vector<int>& nums) {
    int n = nums.size();
    if (n == 0) return 0;
    
    int left = 0, sum = 0, minLen = n + 1;
    for (int right = 0; right < n; ++right) {
        sum += nums[right];
        while (sum >= target && left <= right) {
            minLen = min(minLen, right - left + 1);
            sum -= nums[left++];
        }
    }
    return minLen == n + 1 ? 0 : minLen;
}
  • 易错点/优化点:

    1. 内层 while:当 sum >= target 时不断缩小左指针,直到不满足为止(这样保证每次都取到当前最小)。
    2. 初始化 minLen 为 n+1,最后判断是否更新过。
    3. 数组元素都是正整数 → 右指针只需向右移动一次,O(n) 时间。
    4. 示例:target = 7, nums = [2,3,1,2,4,3] → 2(子数组 [4,3]) target = 4, nums = [1,4,4] → 1([4])
  1. 知识点部分(滑动窗口模板总结) 可变滑动窗口通用模板(今天重点)

    • 核心:右指针一直扩张,左指针只在满足条件时收缩。
    • 适用场景:最小/最大长度子数组、包含所有字符的最小子串等。
    • 与固定窗口(如字母异位词)的区别:固定窗口长度不变,这里长度动态变化。
    • 面试常问:如果数组有负数怎么办?(滑动窗口失效,需要前缀和 + 哈希或二分)。
    • 今天这题因为“正整数”才能用滑动窗口,记住这个前提。
  2. 今日感悟 这道题把滑动窗口的“收缩”逻辑体现得淋漓尽致,以前我总是把左右指针搞混,今天手写完才真正理解“右扩左缩”的节奏。公开打卡让我必须把边界和初始化处理干净,不然发出去自己都心虚。Day 8 了,坚持两周快到了,感觉技术自信在一点点回来!

  3. 结束语 明天见! 欢迎评论区:① 你的滑动窗口写法有什么不同? ② 代码哪里还能优化 ③ 你刷滑动窗口系列时最大的收获是什么? #程序员打卡 #LeetCode #滑动窗口 #长度最小的子数组 #Go语言 #C++