There's a solution with O(1)
additional space complexity and O(n)
time complexity.
Since an array is sorted, it makes sense to have two indices: one going from begin to end (say y
), another from end to begin of an array (say x
).
Here's the code:
function averagePair(arr,tar){
// That's now included in for-loop condition
// if (arr.length < 2) {
// return false;
// }
let x = arr.length - 1;
for (var y = 0; y < x; y++) {
// Division may lose precision, so it's better to compare
// arr[x] + arr[y] > 2*tar
// than
// (arr[x] + arr[y]) / 2 > tar
while (y < x && arr[x] + arr[y] > 2*tar) {
x--;
}
if (x != y && arr[x] + arr[y] == 2*tar) {
return true;
}
}
return false;
}
It's kinda two-pointers technique: we'll decrease x
until a[x] + a[y] > 2*tar
for current loop iteration because we need to find the closest match. At the next for-loop iteration a[y]
is greater or equal than the previous one, so it makes no sense to check if a[z] + a[y] == 2*tar
for any z > x
. We'll do this until indices aren't equal, which means there's no match.