长度最小的子数组_优选算法(C++)滑动窗口
滑动窗口算法:
今天我们来学习一个新的算法.滑动窗口解法,但是我们不直接说明此解法,而是先使用暴力解法,再引入滑动窗口来优化,这样才能解决此类问题.
网页直达:
https://leetcode.cn/problems/2VG8Kg
题目解析:
1.数组的数字均为正整数.
2.满足条件(sum>=target)的子数组是连续的.
一.暴力解法:
枚举所有连续的子数组的和O(N^3)
优化:我们知道数组里面都是正整数.那我们的left,right遍历时.我们就要求sum,但是求sum遍历时一定是单调递增的,在满足第一个sum>=target,求和时遍历的指针就不回退求和,利用单调性,减少了很多没有必要的枚举行为.
二.滑动窗口算法:
怎么用滑动窗口算法呢?
1.left=0;right=0;
2.进窗口
3.判断(这里就是判断完之后就更新minlen)
4.出窗口
5.什么时候更新结果呢?就题目而论
同样的,我们还是要勤画图来了解其中的过程
代码实现:
无注释:
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int right=0,left=0;int sum=0;int minlen=INT_MAX;int n=nums.size();for(int right=0;right<n;right++){sum+=nums[right];while(sum>=target){int curlen=right-left+1;if(minlen>curlen){minlen=curlen;}sum -= nums[left]; // 移除左元素,否则sum不会减小left++;}}return minlen==INT_MAX?0:minlen;}
};
详解,注释:
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int right=0,left=0;//左右指针int sum=0;int minlen=INT_MAX;int n=nums.size();for(int right=0;right<n;right++)//右元素遍历{sum+=nums[right];//增加右元素,相当于扩大窗口while(sum>=target){int curlen=right-left+1;//计算长度if(minlen>curlen)//更新最小长度{minlen=curlen;}sum -= nums[left]; // 移除左元素,否则sum不会减小left++;//左元素遍历}}return minlen==INT_MAX?0:minlen;//存不存在不满足>=target的情况}
};