题目:209. 长度最小的子数组(Minimum Size Subarray Sum)
一、题目描述给定一个含有n个正整数的数组nums和一个正整数target。找出该数组中满足其总和大于等于 target的长度最小的连续子数组并返回其长度。如果不存在符合条件的子数组返回0。示例 1输入: target 7, nums [2,3,1,2,4,3] 输出: 2 解释: 子数组 [4,3] 的和为 7长度最短。示例 2输入: target 4, nums [1,4,4] 输出: 1示例 3输入: target 11, nums [1,1,1,1,1,1,1,1] 输出: 0提示1 target 10^91 nums.length 10^51 nums[i] 10^4二、解题思路1. 滑动窗口双指针由于数组元素全部是正整数这就保证了窗口的和只会增大或减小可以用双指针维护一个连续窗口[left, right]right向右移动累加sum当sum target时尝试缩小左边界left更新最小长度重复上述过程直到遍历完整个数组这种方法只需要一次遍历时间复杂度为O(n)。2. 示例演示target 7 nums [2,3,1,2,4,3] 窗口移动过程 right0 sum2 right1 sum5 right2 sum6 right3 sum8 7 → 长度4 缩小 left → sum6 right4 sum10 7 → 长度4 缩小 left → sum7 → 长度3 right5 sum9 7 → 长度3 缩小 left → sum7 → 长度2 最优三、C语言实现#include stdio.h int minSubArrayLen(int target, int* nums, int numsSize) { int left 0, sum 0; int minLen numsSize 1; for (int right 0; right numsSize; right) { sum nums[right]; while (sum target) { int len right - left 1; if (len minLen) minLen len; sum - nums[left]; left; } } return (minLen numsSize 1) ? 0 : minLen; } // 测试 int main() { int nums[] {2,3,1,2,4,3}; int target 7; printf(%d\n, minSubArrayLen(target, nums, 6)); // 输出 2 return 0; }四、复杂度分析类型复杂度时间O(n)空间O(1)时间复杂度 O(n)左右指针各移动一次最多 2n 次操作空间复杂度 O(1)仅用固定几个变量存储五、扩展进阶如果数组中包含负数或要求O(n log n)时间可以使用前缀和 二分查找构造前缀和数组prefixSum对每个i找最小j满足prefixSum[j] - prefixSum[i] target使用二分搜索加速查找整体复杂度 O(n log n)不过在面试中滑动窗口 O(n)已经是最优解非常高效。六、总结本题滑动窗口思路清晰适合数组元素为正数的场景面试中常用模板维护左右指针left,right积累窗口和sum当满足条件时更新答案并缩小左边界时间复杂度 O(n)空间复杂度 O(1)非常适合大数组