Let [a_1 a_2 ... a_n] be a list of distinct integers in the range [1,10n]. Give an algorithm that returns true if there are three distinct elements x,y,z such that -1 <= x+y-z <= 1, and false otherwise.
A brute force algorithm (checking all possible combinations of x+y-z, runs in time O(n^3). Are there more efficient algorithms?
Yes, there is. Here is an
O(n^2)worst case algorithm that usesO(n)additional space.The idea is to check for all possible pairs (instead of triples), and iteratively marks which elements you have already seen, and compare against them the sum of each pair.
For each pair, check its sum has matching element which is exactly the sum (
x+y-z == 0) or an element you can get to if you add 1 (x+y+1-z == 0 -> x+y-z = -1) or you can get to if you reduce 1 (x+y-1-z == 0 -> x + y - z == 1)Pseudo code:
Note that we iterate
ifromnto 1, becausez > xandz > y– and we want to make sure we are checking all pairs with element that is already in the list if it is thereCorrectness Proof:
If there is a solution
x+y-z = 0– thenz > xandz > y(all elements are positive distinct integers).Without loss of generality, let’s assume
x > y. So, when iteratingarr[i]=xin outer loop, there is somej<isuch thatarr[j]=y. Also, sincez>x–mark[z] == true– since we marked it when we previously iterated it.Thus: The algorithm will find
mark[arr[x] + arr[y]] == true, and yieldtrue.similar proof for the
+-1cases.If the algorithm yielded true, then it found one of the conditions true. Let’s assume it is
mark[arr[i] + arr[j]](The proof for the other cases will be similar).So, we found out
mark[arr[i] + arr[j]] == true– so we inserted it since there is some elementzsuch thatz = arr[i] + arr[j], and the algorithm is correct for this case.