问题
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
例子
思路
-
方法1
-
方法2
双指针 滑动窗口
-
方法3
二分检测窗口大小是否满足
代码
//方法1
class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums.length==0) return 0;
int min = Integer.MAX_VALUE;
for(int i=0; i<nums.length; i++) {
int sum = 0;
for(int j=i; j<nums.length; j++) {
sum+=nums[j];
if(sum>=s)
{
if(j-i+1<min) min = j-i+1;
break;
}
}
}
//如果min=MAX,表明不存在
return min==Integer.MAX_VALUE?0:min;
}
}
//方法2
class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums.length==0) return 0;
int min = Integer.MAX_VALUE;
int i=0,j=0;
int sum=0;
//因为求最小长度,所以,从i=0,j=0开始,而不是i=0,j=len-1
while(i<=j && j<nums.length) {
if(sum+nums[j]>=s) {
if(j-i+1<min) min=j-i+1;
sum-=nums[i];
i++;
}else{
sum+=nums[j];
j++;
}
}
//如果min=MAX,表明不存在
return min==Integer.MAX_VALUE?0:min;
}
}
//方法3
class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums.length==0) return 0;
//窗口:1~nums.length
int i=1,j=nums.length;
int min=0;
while(i<=j) {
int m = i+(j-i)/2;
if(check(nums,s,m))
{
min = m;
j=m-1;
}else{
i=m+1;
}
}
return min;
}
//这个窗口的行不行
public boolean check(int[] nums, int s, int window) {
int sum=0;
for(int i=0; i<nums.length; i++) {
sum+=nums[i];
if(i>=window) {
sum-=nums[i-window] ;
}
if(sum>=s) return true;
}
return false;
}
}