(一)问题描述
leetcode题目链接https://leetcode.cn/problems/minimum-size-subarray-sum/description/
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 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<=taget<=10^9
- 1<=nums.length<=10^5
- 1<=nums[i]<=10^5
(二)关键词提取
- 连续子序列
数组本身是连续的,这里要找的又是连续的子序列(数组中的一段),因此可以采用滑动窗口来解决问题。
(三)解题思路
滑动窗口也是两个指针,但是我们取的是两个指针中间的部分,并且两个指针及其中间的部分是在数组上来回移动的,像一个滑动的窗口。左指针代表窗口的起点,右指针代表窗口的终点。移动右指针改变窗口的位置,固定右指针后移动左指针来缩小窗口,直至找到满足条件的最短子序列。
- 用一个整数sum来统计窗口内各个元素的和
- sum大于等于target时,说明当前窗口区间有满足条件的子序列。否则右指针继续向右移动。
- 移动左指针,每次移动后要从sum里减去移除的左侧元素,直到找到满足条件的最短子序列
- 右指针向右移动,重复上面的步骤
伪代码:
minSubArrayLen (target, nums[])
//查找数组中满足和大于等于target的最短连续子序列
//输入:条件值target,目标数组nums[]
//输出:最短连续子序列长度result
result←Integer_MAX_VALUE, left←0, right←0, sum←0
for right←0; right<nums.length; right++
sum←sum+nums[right]
while sum>=target
result←min (result, right-left+1)
sum←sum-nums[left]
left←left+1
if result==Interger_MAX_VALUE
return 0
else
return result
(四)易错点
1. while(sum>=target) 还是 if(sum>=target)。举个例子,符合条件的窗口是[1,1,1,1,100],目标值也是100,这个时候最短序列长度是1。但如果是if,到这里这一步就结束了,取结果是5,这显然是错误的。所以左指针也应该移动,把满足条件的子序列缩到最短。
2. 最后返回结果之前要判断一下,有可能没找到满足条件的子序列,这步别忘了。