题目描述如下:
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 class Solution {
public int minSubArrayLen(int s, int[] nums) {
int res = Integer.MAX_VALUE;
int arrLen = nums.length;
int first = 0, second = 0;
int currSum = 0;
boolean flag = true;
while(first < arrLen){
if(flag){
currSum += nums[first];
flag = false;
}
if(currSum >= s){
if(res > first - second + 1){
res = first - second + 1;
}
currSum -= nums[second];
second ++;
}else{
first ++;
flag = true;
}
}
return res;
}
}
这样的做法超时,也就是说每次循环若只移动两个指针中的其一一格是不够的。于是进行优化,即在一次循环中,让前后指针在给定的范围内不断移动,这样就可以减少判断的次数。修改代码如下:
public class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums.length == 0) return 0;
int res = Integer.MAX_VALUE;
int arrLen = nums.length;
int first = 0, second = 0;
int currSum = 0;
while(first < arrLen && second < arrLen){
while(currSum < s && first < arrLen){
currSum += nums[first];
first++;
}
while(currSum >= s && second < first){
if(res > first - second){
res = first - second;
}
currSum -= nums[second];
second ++;
}
}
return res;
}
}
但是光做到这样还是不行,还需要对特殊条件进行判断:
1、输入的数组为空时,返回的值是0;
2、当数组无法满足给定数值时,返回的也是0;
加上对特殊条件的鉴别,最终代码如下:
public class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums.length == 0) return 0;
int res = Integer.MAX_VALUE;
int arrLen = nums.length;
int first = 0, second = 0;
int currSum = 0;
while(first < arrLen && second < arrLen){
while(currSum < s && first < arrLen){
currSum += nums[first];
first++;
}
while(currSum >= s && second < first){
if(res > first - second){
res = first - second;
}
currSum -= nums[second];
second ++;
}
}
return res == Integer.MAX_VALUE ? 0 : res;
}
}
题目链接:https://leetcode.com/problems/minimum-size-subarray-sum/