题目概述
题目链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum/
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
先来审个题吧
先划出题目中的关键字
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
≥:代码中注意条件即可
连续:说明题目的答案是在一个连续的数组索引的区间内
最小:我们要使这个区间范围尽可能地小
思路
既然答案是一个连续的区间,我们可以使用两个指针 i i i 和 j j j 标记区间的起始端点。算出 [ i , j ] [i,j] [i,j]内的数值总和,并与题中给定的正整数 s s s 比较。假设给定数组为nums,给定正整数为target。
if(sum >= target)
sum -= nums[i++]; //符合题意,要使区间大小更小,区间起始位置向前移
else
sum += nums[j++]; //不符合题意,要使区间总和 ≥ target,区间终止位置向后移
这种双指针的问题很像是一个窗口的移动,所以又叫做滑动窗口问题,这道题是滑动窗口中非常经典的例题。
上代码
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//赋予res初始值,用于判断是否存在符合题意的子数组
int res=nums.length+1;
int temp=res;
//区间起始位置指针
int i=0;
int sum=0;
//用循环变量控制区间终止位置指针,防止指针越界
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=target){
temp=j-i+1;
res=temp<res ? temp : res;
sum-=nums[i++];
}
}
return res==nums.length+1 ? 0 : res;
}
}