find pair of numbers in array that add to given sum
If you have a sorted array you can find such a pair in O(n) by moving two pointers toward the middle
i = 0
j = n-1
while(i < j){
if (a[i] + a[j] == target) return (i, j);
else if (a[i] + a[j] < target) i += 1;
else if (a[i] + a[j] > target) j -= 1;
}
return NOT_FOUND;
The sorting can be made O(N) if you have a bound on the size of the numbers (or if the the array is already sorted in the first place). Even then, a log n factor is really small and I don't want to bother to shave it off.
proof:
If there is a solution (i*, j*)
, suppose, without loss of generality, that i
reaches i*
before j
reaches j*
. Since for all j'
between j*
and j
we know that a[j'] > a[j*]
we can extrapolate that a[i] + a[j'] > a[i*] + a[j*] = target
and, therefore, that all the following steps of the algorithm will cause j to decrease until it reaches j*
(or an equal value) without giving i
a chance to advance forward and "miss" the solution.
The interpretation in the other direction is similar.
An O(N)
time and O(1)
space solution that works on a sorted array:
Let M
be the value you're after. Use two pointers, X
and Y
. Start X=0
at the beginning and Y=N-1
at the end. Compute the sum sum = array[X] + array[Y]
. If sum > M
, then decrement Y
, otherwise increment X
. If the pointers cross, then no solution exists.
You can sort in place to get this for a general array, but I'm not certain there is an O(N)
time and O(1)
space solution in general.