I was solving the problem Minimum Size Subarray Sum. I am trying to solve it by using binary search on a prefix sum array that solves the problem in n*log(n) complexity.
I managed to get it working however I do not understand why my solution worked.
Thought Process
My thought process is as follows:
Step 1: Given the original array nums, first I create a prefix sum array as follows:
Step 2: I then apply the following logic:
/* need to find min r-l+1 such that prefix[r] - prefix[l-1] >= k prefix[r] - k >= prefix[l-1] tgt >= prefix[l-1] */
Step 3: I iterate over the prefix[] array - this represents
prefix[r]
. Sincenums
has all positive values, theprefix
array is always increasing - ie it is sorted. I then use binary search onprefix
to findprefix[l-1]
values that satisfy the property described above wheretgt >= prefix[l-1]
.
Code
My code is as follows:
public int minSubArrayLen(int s, int[] nums) {
int[] prefix = new int[nums.length];
int res = Integer.MAX_VALUE;
for(int i=0; i<nums.length; i++) {
if(i==0)
prefix[i] = nums[i];
else
prefix[i] = nums[i] + prefix[i-1];
}
for(int i = 0; i<prefix.length; i++) {
int tgt = prefix[i] - s;
int index = binarySearch(0, i, tgt, prefix);
if(index >= 0) {
res = Math.min(res, i-index+1);
}
}
return res == Integer.MAX_VALUE? 0 : res;
}
private int binarySearch(int l, int r, int tgt, int[] a) {
int res = -1;
while(l<=r) {
int mid = l + (r-l)/2;
if(tgt >= a[mid]) {
res = mid;
l = mid+1;
} else {
r = mid-1;
}
}
return res;
}
This does not work. So I made the following change to the prefix array such that it starts with 0:
int[] prefix = new int[nums.length+1];
for(int i=0; i<nums.length; i++)
prefix[i+1] = nums[i] + prefix[i];
And I edited the way the subarray is calculated to account for these changes:
res = Math.min(res, i-index);
And my algorithm now worked.
My questions
I dont really understand what is happening here. Why did my initial code not work and why did it work when I changed the prefix sum array?
What changes do I need to make to my algorithm if I want to use the original prefix sum array (ie the one that does not start with 0)