题目描述:
Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead.
For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.
这个题一开始没怎么弄清题意,写了一个回溯算法求子数组,但是我求出来的并不是连续子数组,可以参考一下:
public int minSubArrayLen(int s, int[] nums) {
int minLen=Integer.MAX_VALUE,sum=0,start=0,len=0;
List<Integer> list=new ArrayList<Integer>();
trace(list, s, nums, sum, len, start);
for (int i = 0; i < list.size(); i++)
minLen=minLen<list.get(i)?minLen:list.get(i);
return minLen;
}
public void trace(List<Integer> list,int s,int[] nums,int sum,int len,int start){
if(sum==s){
list.add(len);
return;
}
if(sum>s)
return;
for(int i=start;i<nums.length;i++){
trace(list, s, nums, sum+nums[i], len+1, i+1);
}
}
后来看到连续子数组之后,我的第一反应就是二分法,于是就想到了Maximum Subarray这一题。但是这个题用那个思路解不出来。换个思路就想到了两个指针的办法,代码如下所示:
public int minSubArrayLen(int s, int[] nums) {
int left=0,right=0;
int len=0,minLen=Integer.MAX_VALUE,n=nums.length;
if(n==0)
return 0;
int sum=nums[0];
while(right<n){
//先比较,再移动
if(sum>=s){
len=right-left+1;
minLen=len<minLen?len:minLen;
}
if(sum<=s||left==right){
right++;
if(right==n)
break;
sum+=nums[right];
}else{
sum-=nums[left++];
}
}
//下面这一部分不需要,因为当right==n-1的时候left已经在往右走,当right==n直接结束
/*while(sum>=s){
minLen=len<minLen?len:minLen;
len--;
sum-=nums[left++];
}*/
return minLen==Integer.MAX_VALUE?0:minLen;
}