题目:
Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.
Example:
Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.
Follow up:
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
分析:
- 整体思路应该是滑动窗口。即左指针和右指针从最左边一直伸缩着向前移动。
- 当和值小于目标值时,右指针向右移动,增大窗口;大于目标值时,左指针向右移动,减小窗口。
- 碰到满足条件的和值时,更新最短子串长度。
- 不用担心漏掉哪种情况,因为在当前情况之前,每一次满足条件的最小窗口的长度都会被记录下来。反而是如果两个指针从两头(对撞指针)走时会有可能跳过。对了,这个不是有序数组,所以不能从两头走。
- bug分析:
(一开始没有判断结果的范围,直接return了res,这样当不存在时,并不会返回0。)
答案:
Runtime: 2 ms, faster than 29.07% of Java online submissions for Minimum Size Subarray Sum.
Memory Usage: 37.4 MB, less than 60.94% of Java online submissions for Minimum Size Subarray Sum.
private static int minimumSizeSubarray2(int s,int[] nums) {
int res = nums.length+1; //初始结果为数组长度加一,这样后面只要出现满足条件的,一定小于这个值。
int l = 0;
int r = -1;
int sum = 0; //记录每次窗口里的和值
//不用担心移动过程中超出数组范围,只要满足过条件,就 会记录在res里,而且移动过程中窗口里的和值也会一直记录。
while (l<nums.length) { //l最大可以取到数组的最右边
if(sum<s && r<nums.length-1) { //注意这个边界是r只能到他能取到的值的前一个
r++;
sum = sum + nums[r];
}
else {
sum = sum - nums[l];
l++;
}
if(sum >= s) {
res = Math.min(res, r-l+1);
}
}
if(res > 0 && res <= nums.length) {
return res;
}
else {
return 0;
}
}