力扣(LeetCode) ——209. 长度最小的子数组(C++)
题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例1:
输入: target = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的子数组。
示例2:
输入: target = 4, nums = [1,4,4]
输出: 1
示例2:
输入: target = 11, nums = [1,1,1,1,1,1,1,1]
输出: 0
解题思路:
利用滑动窗口来解决问题:
- 1. 初始化关键变量:
- 定义两个指针
left和right,均初始指向数组起始位置(下标 0),且 right 始终不超过数组长度(right < nums.size()避免越界); - 创建变量
sum,用于累计当前窗口([left, right]区间)内元素的总和,初始值为 0; - 创建变量
len,用于记录满足条件的子数组最小长度,初始值设为整数最大值INT_MAX(方便后续通过min函数更新最小值)。 2. 扩展窗口累加总和: - 让 right 指针从数组起始位置开始遍历(逐步扩展窗口右边界),每次遍历将当前 nums[right] 的值加入 sum,完成窗口总和的更新。 3. 收缩窗口优化长度:
- 当窗口总和
sum ≥ target时(满足 “总和≥target” 的条件),先计算当前窗口的长度(right - left + 1),并与 len 比较,取较小值更新 len(确保 len 始终是当前找到的最小长度); - 之后通过
sum -= nums[left]移除窗口左边界的元素(收缩窗口),并将 left 指针向右移动一位,尝试找到更短的满足条件的子数组; - 重复此步骤(用 while 循环),直到 sum < target 为止(此时窗口不再满足条件,停止收缩)。 4. 返回最终结果:
- 遍历结束后,检查 len 的值:若 len 仍为
INT_MAX,说明遍历完所有元素后,没有找到任何总和 ≥ target 的子数组,返回 0; - 若 len 已被更新(不为
INT_MAX),则 len 即为满足条件的最小子数组长度,返回 len。
最终代码:
int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size();int sum = 0, len = INT_MAX;for(int left = 0,right = 0;right < n; right++){sum += nums[right];//进窗口while(sum >= target)//判断{len = min(len, right - left + 1);//更新结果sum -=nums[left++];//出窗口}}return len == INT_MAX? 0 : len;}
赶紧动起手来吧!!!
点击下方即可跳转
长度最小的子数组
