大家好,我是小卡皮巴拉
文章目录
目录
力扣题目:长度最小的子数组
题目描述
解题思路
问题理解
算法选择
具体思路
解题要点
完整代码(C++)
兄弟们共勉 !!!
每篇前言
博客主页:小卡皮巴拉
咱的口号:小比特,大梦想
作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。
原题链接:209. 长度最小的子数组 - 力扣(LeetCode)
给定一个含有 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
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0
本题要求在给定的正整数数组 nums
中,找出总和大于等于给定正整数 target
的长度最小的子数组,并返回该子数组的长度。若不存在这样的子数组,则返回 0。
使用滑动窗口算法来解决此问题。滑动窗口算法适合处理数组或字符串中的子数组、子串问题,通过动态调整窗口的左右边界,可以高效地找到满足条件的最小子数组。
初始化变量:
获取数组 nums
的长度 n
。
定义变量 sum
用于记录当前滑动窗口内元素的总和,初始化为 0。
定义变量 len
用于记录满足条件的最小子数组的长度,初始化为 INT_MAX
。
使用 left
和 right
两个指针来界定滑动窗口的左右边界,初始时都指向数组的起始位置。
移动右指针扩展窗口:
使用 for
循环让 right
指针从左到右遍历数组。在每次循环中,将当前元素 nums[right]
加入窗口,更新 sum
的值。
调整窗口:
当 sum
大于等于 target
时,说明当前窗口内元素的总和满足条件。此时,计算当前窗口的长度 right - left + 1
,并与 len
比较,取较小值更新 len
。
然后移动 left
指针缩小窗口,将 nums[left]
从窗口中移除,更新 sum
的值,直到 sum
小于 target
。
返回结果:
遍历结束后,如果 len
仍然等于 INT_MAX
,说明没有找到满足条件的子数组,返回 0;否则返回 len
。
窗口的动态调整:根据窗口内元素总和与 target
的大小关系,合理移动 left
和 right
指针,调整窗口大小,确保找到最小长度的子数组。
结果的更新:每次窗口内元素总和满足条件时,及时更新最小子数组的长度 len
。
边界情况处理:若最终 len
仍为 INT_MAX
,说明不存在满足条件的子数组,返回 0。
class Solution {
public:
int minSubArrayLen(int target, vector& nums) {
int n = nums.size(); // 获取数组的长度
int sum = 0; // 记录当前滑动窗口内元素的总和
int len = INT_MAX; // 记录满足条件的最小子数组的长度,初始化为 INT_MAX
// 使用滑动窗口
for (int left = 0, right = 0; right < n; right++) {
sum += nums[right]; // 将当前元素加入窗口,更新总和
while (sum >= target) { // 当窗口内元素总和大于等于 target 时
len = min(len, right - left + 1); // 更新最小子数组的长度
sum -= nums[left++]; // 移除左指针指向的元素,缩小窗口
}
}
return len == INT_MAX ? 0 : len; // 如果 len 仍为 INT_MAX,说明不存在满足条件的子数组,返回 0;否则返回 len
}
};
码字不易,求个三连
抱拳了兄弟们!