双指针,长度最小的子数组
1. 题目描述
难易度:中等
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
2. 思路分析
以示例s = 7, nums = [2,3,1,2,4,3]为例进行分析
- 定义sum=0,index=0
- for循环,每次取一个元素,首先进行判断,若该元素大于等于s则可以直接返回1
- 使用sum保存每次取到的元素的和
- 若sum>=s则将其长度赋值给length,例如2+3+1+2>s,则更新length为4
- 减去index下标处的元素,继续进行循环比较,例如2+3+1+2>s,则减去nums[index],即减去2(因为此时index=0),index++
- 继续下一轮判断,具体可看代码注释
3. 代码演示
class Solution {
public int minSubArrayLen(int s, int[] nums) {
//排除null和数组等于0
if (nums == null || nums.length == 0) {
return 0;
}
//数组只有一个元素,可以直接判断返回
if (nums.length == 1) {
if (nums[0] >= s) {
return 1;
} else {
return 0;
}
}
//初始假设length为数组长度
int length = nums.length;
int index = 0;
int sum = 0;
boolean flag = false;
for (int i = 0; i < nums.length; i++) {
//假设取到的元素大于等于s则可以直接返回1
if (nums[i] >= s) {
return 1;
}
//求取到的元素之和
sum += nums[i];
//当sum>=s时
while (sum >= s) {
flag = true;
//截取index和i位置的差值,和length进行比较,将较小的复制给length
//即更新length
length = Math.min((i + 1 - index), length);
//减去index位置的元素
sum -= nums[index];
//index后移
index++;
}
}
//假设flag为true则说明存在sum>=s的情况,则返回length
if (flag) {
return length;
} else {//flag为假则说明整个数列不存在sum>=s的情况,则返回0
return 0;
}
}
}