Problem
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 -1 instead.
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.
Challenge
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(nlogn).
Note
做一个窗口minsize,满足sum >= s
的左界到右界的距离最小值为所求。while
循环的约束条件要注意,不要遗漏:right不能超过nums[]的长度,但可以等于,因为存在nums[]所有元素之和为s的极端情况。
在sum < s
时,sum加上右指针的元素,同时right指针后移,但是注意当right = nums.length
时,sum不能加(元素不存在!),所以sum += nums[right]
要加限制条件。
在sum >= s
时,先更新窗口为当前循环后的最小值,减去最左元素,left指针后移。
Solution
public class Solution {
public int minimumSize(int[] nums, int s) {
if (nums == null) return -1;
int left = 0, right = 0, sum = 0, minsize = Integer.MAX_VALUE;
while (right <= nums.length && left <= right) {
if (sum < s) {
if (right < nums.length) {
sum += nums[right];
}
right++;
}
else {
minsize = Math.min(minsize, right - left);
sum -= nums[left];
left++;
}
}
return minsize <= nums.length ? minsize : -1;
}
}
Binary Search:
public class Solution {
public int minimumSize(int[] nums, int s) {
if (nums == null || nums.length == 0) return -1;
int[] sum = new int[nums.length+1];
int minsize = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
sum[i+1] = sum[i] + nums[i];
if (sum[i+1] >= s) {
int left = helper(sum, sum[i+1]-s, 0, i+1);
minsize = Math.min(minsize, i+1-left);
}
}
return minsize > nums.length ? -1 : minsize;
}
public int helper(int[] A, int target, int start, int end) {
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (A[mid] < target) start = mid;
else end = mid; //A[mid] = target is in this branch
}
if (A[end] <= target) return end;//Make sure return the same brunch
//---->end, when A[end] = target
else return start;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。