LeetCode 209. Minimum Size Subarray Sum ?
given an array and a positive integer s, we have to find the shortest subarray such that the sum of its element >= s.
the first thought in my mind is maintain a sliding windows, and always have the minimum length;
I was trying to solve it using sliding window:
但是下面的代码怎么搞都不对
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int i = 0;
int j = 0;
int min = Integer.MAX_VALUE;
int sum = 0;
while (j < nums.length) {
while (j < nums.length - 1 && sum < s) {
sum += nums[j++];
}
while (sum >= s) {
sum -= nums[i++];
}
min = Math.min(min, j - i + 2); //j stoped at the posistion makes sum>=s, and i stopped at the position where makes sum<s, so i should be in the position of i-1, and [i-1, j] should be the right position
j++;
}
return min == Integer.MAX_VALUE? 0: min;
}
}
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int i = 0;
int j = 0;
int min = Integer.MAX_VALUE;
int sum = 0;
while (j < nums.length) {
sum += nums[j];
if (sum < s) {
j++;
continue;
}
while (sum >= s) {
sum -= nums[i++];
}
min = Math.min(min, j - i + 2);
j++;
}
return min == Integer.MAX_VALUE? 0: min;
}
}
同时 这个题目还跟二分法有关。
那么是怎么样跟二分法有关呢?看起来牛风马不相及的事情。而且原数组还没有排序 当然也不能排序。
回忆一下我们如何快速计算sunarray和或者乘积
对了!就是用prefix sum/multiple.
但是就算这样也不能想出来怎么样才能检索和大于s的子数组。
所以在下面的代码里面:
for (int i = 0; i < sums.length; i++) {
int end = binarySearch(i + 1, sums.length - 1, sums[i] + s, sums); //this binary search get the first one which subarray sum larger or equals to s.
}
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int[] sums = new int[nums.length + 1];
for (int i = 1; i < sums.length; i++) {
sums[i] = sums[i - 1] + nums[i - 1];
}
int minLen = Integer.MAX_VALUE;
for (int i = 0; i < sums.length; i++) {
int end = binarySearch(i + 1, sums.length - 1, sums[i] + s, sums); //trying to find the subarray between i+1 and the end which the sum>=s. we have to find the first that satisfy this need so that makes shorter
if (end == sums.length) break; //if we can't find any, then it means that even we added tham all, the sum still less than s, there is no need to search more, just break.
if (end - i < minLen) minLen = end - i; //update minLen if necessary
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
private int binarySearch(int lo, int hi, int target, int[] sums) { //find the target between sums[lo, hi], if not trying to get the first one that is larger than it
while (lo <= hi) {
int mid = (hi - lo) / 2 + lo;
if (sums[mid] == target) {
return mid;
} else if (sums[mid] > target) {
hi = mid - 1;
} else {
lo = mid + 1;
}
}
return lo;
}
}

浙公网安备 33010602011771号