leetcode 209. 长度最小的子数组(详解)
Posted AI_ELF
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 209. 长度最小的子数组(详解)相关的知识,希望对你有一定的参考价值。
给定一个含有 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
提示:
- 1 <= target <= 109
- 1 <= nums.length <= 105
- 1 <= nums[i] <= 105
思路:
-
暴力算法:使用两个for循环,不断的寻找符合条件的子数组
-
滑动窗口:不断地调节子数组的起始位置和终止位置,从而得出我们想要的结果
-
实现滑动窗口步骤:
-
- 窗口内的元素:保持窗口内数值总和大于或等于target的长度最小的连续子数组
-
- 移动窗口的起始位置:如果当前窗口的值大于s,则窗口向前移动(窗口缩小)
-
- 移动窗口的结束位置:窗口的结束位置就是for循环遍历数组的指针
代码如下:
1.暴力解法
class Solution
public:
int minSubArrayLen(int target, vector<int>& nums)
int result=INT32_MAX;//最终结果
int sum=0;//子数组的元素之和
int countlen=0; //子数组的长度
for(int i=0;i<nums.size();i++) //设置子数组起点为i
sum=0;
for(int j=i;j<nums.size();j++) //设置子数组最终位置为j
sum+=nums[j];
if(sum>=target) //一旦发现子数组元素之和超过target就更新result
countlen=j-i+1; //获取子数组的长度
result=countlen<result?countlen:result;
break;
// 如果result没有被赋值,则返回0,说明没有符合条件的子数组
if(result==INT32_MAX)
return 0;
return result;
;
- 时间复杂度O(N^2)
- 空间复杂度O(1)
2. 滑动窗口
class Solution
public:
int minSubArrayLen(int target, vector<int>& nums)
int result=INT32_MAX;
int i=0; //滑动窗口的起始位置
int sum=0; //滑动窗口的数值之和
int countlen=0; //滑动窗口的长度
for(int j=0;j<nums.size();j++)
sum+=nums[j];
//注意这里使用while每次更新i(起始位置)并不断比较子数组是否符合条件
while(sum>=target)
countlen=j-i+1; //获取子数组的长度
result=result<countlen?result:countlen;
//这里体现出滑动窗口的精髓之处,不断变更i(子数组的起始位置)
sum-=nums[i++];
// 如果result没有被赋值,则返回0,说明没有符合条件的子数组
return result==INT32_MAX?0:result;
;
- 时间复杂度O(N)
- 空间复杂度O(1)
总结:滑动窗口的精妙之处在于根据当前子数组和的大小,不断调节子数组的起始位置,从而将时间复杂度O(N^2)降为O(N)
以上是关于leetcode 209. 长度最小的子数组(详解)的主要内容,如果未能解决你的问题,请参考以下文章