1.题目:
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
https://leetcode-cn.com/problems/minimum-size-subarray-sum/
2.思路:滑动窗口
使用队列相加(实际上我们也可以把它称作是滑动窗口,这里的队列其实就相当于一个窗口)
(1)我们把数组中的元素不停的入队,直到总和大于等于 s 为止,
(2)接着记录下队列中元素的个数,然后再不停的出队,直到队列中元素的和小于 s 为止(如果不小于 s,也要记录下队列中元素的个数,这个数其实就是不小于 s 的连续子数组长度,我们要记录最小的即可)。
(3)接着再把数组中的元素添加到队列中……重复上面的操作,直到数组中的元素全部使用完为止。
这里以 [2,3,1,2,4,3] 举例画个图来看下:
上面画的是使用队列,但在代码中我们不直接使用队列,我们使用两个指针,一个指向队头一个指向队尾,我们来看下代码
3.求解:
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
//1. 输入相关数据
int s = sc.nextInt();
int n = sc.nextInt();
int a[] = new int[n];
for(int i=0;i<n;i++) {
a[i] = sc.nextInt();
}
//2.使用滑动窗口,来获取长度最小的连续数组
/*
* (1)首先初始化当前连续数组的开始和结束下标,以及 当前连续数组的最小长度
* (2)从第一个元素开始,依次加入元素
* 若加入当前元素后,当前连续数组的总和>=s:
* 则从第一个元素开始移除,直到当前元素的总和<s
* 并且记录连续数组总和>=s的元素个数,保留当前最小的
*当前连续数组总和<s,则继续加入元素
* * */
int start=0,end=0,sum=0,min=Integer.MIN_VALUE;
// 遍历完整个数组时结束
while(end<a.length) {
sum+=a[end]; //加入元素
while(sum>=s) {//移除元素,直到小于s
//记录当前总和>=s的连续数组的最小长度
min = Math.min(min, end-start+1);
sum-=a[start++]; //移除开始元素
}
end++;//向右移动一位,以加入该元素
}
//3.输出最小的连续子数组长度
System.out.println(min==Integer.MIN_VALUE? 0 : min);
}
}