If we calculated the average of k
elements from 0 to k
, what we can tell about average from 1 to k
, or about from 0 to k + 1
?
Both averages 1 to k
and 0 to k + 1
are equal or greater to the average of first k
elemnts.
Why?
Going from subset from 0 to k
to subset from 1 to k
, means removing the least element, so may not decrease total average.
Going from subset from 0 to k
to subset from 0 to k + 1
, means adding an element which isn't smaller that every other, so it may not decrease total average.
Do we know which number from given array must be part of the result? Yes, this is the last smaller or equal to the target. Why?
When it is equal, then we are done
When it is not equal, then we need to have both bigger and lower elements.
Then, we maintain the average increasing it by adding elements from right side, and decreasing from left side.
public static int[] findMean(int[] input, int target) {
int firstGreater = 0;
int n = input.length;
while(firstGreater < n && input[firstGreater] <= target) firstGreater++; // use binary search instead!
if(firstGreater == 0 || firstGreater == n) return new int[]{-1,-1};
int left = firstGreater - 1, right = firstGreater;
long sum = input[left];
while ((right < n &&(right - left) * target > sum) || (left > 0 && (right - left) * target < sum)) {
if((right - left) * target > sum) sum += input[right++];
else sum += input[--left];
}
if((right - left) * target != sum) {
left = right = -1;
}
return new int[]{left, right - 1};
}