2 pointers binary search
/*
ans = min(ans, (j - i + 1));
Found the smallest subarray with sum>=s starting with index i, hence move to next index
we can't find a shorter subarray that starts at i
*/
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int minLen = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++){
int sum = 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
if (sum >= s){
minLen = Math.min(minLen, j - i + 1);
break;
}
}
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
}
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int n = nums.length;
int ans = Integer.MAX_VALUE;
int left = 0;
int sum = 0;
for (int i = 0; i < n; i++) {
sum += nums[i];
while (sum >= s) {
ans = Math.min(ans, i + 1 - left);
sum -= nums[left++];
}
}
return (ans != Integer.MAX_VALUE) ? ans : 0;
}
}
/*
⭐️sums[]其实就是sorted array,所以可以用bs
while(i < j)判断最后整个subarray的sum都小于s的情况和上面的条件不一样,因为i和j都指向最后一位,最后j = nums.length
if (j == nums.length) break;
*/
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int sum = 0;
int min = Integer.MAX_VALUE;
int[] sums = new int[nums.length];
for(int i = 0; i < nums.length; i++) {
if(i == 0) {
sums[i] = nums[i];
} else {
sums[i] = nums[i] + sums[i - 1];
}
}
for (int i = 0; i < nums.length; i++) {
int j = findWindowEnd(i, sums, s);
if (j == nums.length)
break;
min = Math.min(j - i + 1, min);
}
return min == Integer.MAX_VALUE ? 0 : min;
}
private int findWindowEnd(int start, int[] sums, int s) {
int i = start, j = sums.length - 1;
int offset = start == 0 ? 0 : sums[start - 1];
while(i <= j) {
int mid = i + (j - i) / 2;
int sum = sums[mid] - offset;
if(sum >= s) {
j = mid - 1;
} else {
i = mid + 1;
}
}
return i;
}
}
/*
⭐️sums[]其实就是sorted array,所以可以用bs
while(i < j)判断最后整个subarray的sum都小于s的情况和上面的条件不一样,因为i和j不能都指向最后一位
if(sums[j] - offset < s) return -1;
*/
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int sum = 0;
int min = Integer.MAX_VALUE;
int[] sums = new int[nums.length];
for(int i = 0; i < nums.length; i++) {
if(i == 0) {
sums[i] = nums[i];
} else {
sums[i] = nums[i] + sums[i - 1];
}
}
for (int i = 0; i < nums.length; i++) {
int j = findWindowEnd(i, sums, s);
if (j == -1)
break;
min = Math.min(j - i + 1, min);
}
return min == Integer.MAX_VALUE ? 0 : min;
}
private int findWindowEnd(int start, int[] sums, int s) {
int i = start, j = sums.length - 1;
int offset = start == 0 ? 0 : sums[start - 1];
if(sums[j] - offset < s) return -1;
while(i < j) {
int mid = i + (j - i) / 2;
int sum = sums[mid] - offset;
if(sum >= s) {
j = mid;
} else {
i = mid + 1;
}
}
return i;
}
}