欢迎来到 CILMY23 的博客
🏆本篇主题为:滑动窗口之209. 长度最小的子数组(力扣)
🏆个人主页:CILMY23-CSDN博客
🏆系列专栏:Python | C++ | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题 | 代码训练营
🏆感谢观看,支持的可以给个一键三连,点赞收藏+评论。如果你觉得有帮助,还可以点点关注
题目:
给定一个含有 n
个正整数的数组和一个正整数 target
。找出该数组中满足其总和大于等于 target
的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
题目解析:
通过题目就可以发现以下信息
- 找到长度最小的子数组
- 子数组求和和target值相同
- 数组和target都是正整数
- 代码返回子数组长度
- 如果不存在符合条件的子数组,返回
0
算法原理:
这题我们用一个高大上的双指针算法 --- "同向双指针(滑动窗口)"
滑动窗口理解起来就像是双指针算法的另外一种用法,有个高大上的名字“同向双指针”。
滑动窗口:
假设有一个数组nums,现在我们用一个框框括起来,我们把这个框框叫做窗口
现在有一个target,要让我们求窗口数之中的和,假设窗口的左边是left,窗口的右边是right,窗口的长度是len = 3,我们求了一个sum表示窗口中的和,因为sum = 6 < target = 7,所以我们可以理解为窗口中的数不够多,这时候窗口就要扩大,也就是right就要加1.
right 向前移动后,我们要再计算sum的值,sum此刻等于8,比target大了,那我们就要缩小这个窗口了,此时不可能让right 缩小,因为right所负责的这个边界是让数组的值进入的,所以要让left++,这个nums数组中的数值 2 就“出窗口了”。当时在出窗口前我们要做到一点,更新结果,更新结果有的时候会在进窗口更新,有的时候是在出窗口前更新,随机应变。那这道题刚好是在判断满足的时候,更新结果,所以更新结果这一步骤不急着去做。
重复之后,我们就可以找到len为2的情况了。
滑动窗口步骤:
1.初始化left和right指针,left = 0,right = 0
2.进窗口
3.判断
出窗口
4.出窗口继续判断
其中2,3步是一直循环的。
更新结果有的时候会在进窗口更新,有的时候是在出窗口前更新,随机应变。
什么时候用?
利用单调性,发现两个指针都可以不回退,都只在同一个方向上移动,这时候就用滑动窗口。
本质是什么?
本质是一个同向双指针
时间复杂度(不要看循环,分析复杂度)
时间复杂度为O(n),最差情况就是right指针和left指针都走完了数组
代码解析:
注意的点:
len 一开始设置成max的最大值,防止每次传出去的值是0
在返回的时候判断一下len的值,因为有可能存在不符合条件的子数组,需要返回 0
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums)
{
int left = 0;
int right = 0;
int len = INT_MAX;
int sum = 0;
for(left = 0,right = 0;right < nums.size();right++)
{
sum += nums[right]; //进窗口
while(sum >= target) //判断
{
len = min(len,right - left +1); //更新结果
sum -= nums[left]; //出窗口
left++;
}
}
return len == INT_MAX ? 0 : len;
}
};
🛎️感谢各位同伴的支持,本期算法专题就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞,收藏+评论,可以的话还希望点点关注,若有不足,欢迎各位在评论区讨论。