1

You are given a sum S and X , you need to find , if it there exist two numbers a and b such that a+b = S and a^b = X I used a loop upto S/2 and check if it is possible or not

for(int i=0;i<=s/2;i++)
{
   if(i^(s-i)==X)
    return true;
}

complexity : O(n)

Need some better approach

Subham Gupta
  • 53
  • 1
  • 5

3 Answers3

7

Given that a+b = (a XOR b) + (a AND b)*2 (from here) we can calculate (a AND b):

If S < X => not possible, otherwise take S-X. If this is odd => not possible, otherwise (a AND b) = (S-X)/2.

now we can look at the bits of a and b individually. Checking all four combinations we see there is only one result that is impossible namely XOR and AND both 1.

So if (a XOR b) AND (a AND b) != 0 there is no solution. Otherwise one can find a and b that solve the equation.

if (S < X) return false;
Y = S - X;
if (Y is odd) return false;
if ((X & (Y/2)) != 0) return false;
return true;
Henry
  • 42,982
  • 7
  • 68
  • 84
  • So, in the question's C-like notation, an `O(1)` solution is `return !((a ^ b) & a & b);`. Returns `true` is there is a solution, `false` if not. It's also possible to find the pairs in `O(log2(max(S, X)))`, but that is an exercise for another day! – Ken Y-N Jul 12 '17 at 06:23
  • Yeah Great got it !!! – Subham Gupta Jul 13 '17 at 05:19
1

Without previous knowledge of the equation, a+b = a^b + (a&b)*2, we can think of another solution. This solution is O(logK) where K is the maximum possible value of S and X. That is, if S and X are unsigned int then K is 2^32 - 1.

Start from the MSB of S and X. With the information that whether summing this bit must provide carry or not, we can check for this bit with condition that whether summing the bits to the right should provide carry or not.

Case1 ) summing must not provide carry

S X | need carry from right
------------------------------
0 0 | no  (a = 0, b = 0)
0 1 | impossible
1 0 | yes (a = 0, b = 0)
1 1 | no  (a = 1, b = 0 or 0,1)

Case2 ) summing must provide carry

S X | need carry from right
------------------------------
0 0 | no  (a = 1, b = 1)
0 1 | yes (a = 1, b = 0 or 0,1)
1 0 | yes (a = 1, b = 1)
1 1 | impossible

There is a special case for the MSB where the carry doesn't matter.

Case3 ) don't care

S X | need carry from right
------------------------------
0 0 | no  (a = 0, b = 0 or 1,1)
0 1 | yes (a = 1, b = 0 or 0,1)
1 0 | yes (a = 0, b = 0 or 1,1)
1 1 | no  (a = 1, b = 0 or 0,1)

Lastly, the LSB must end with 'no need carry from right'.

The implementation and test code is here. It compares the output of the accepted solution and this solution.

nglee
  • 1,913
  • 9
  • 32
0

I assume that you are assuming that your input sequence is sorted.

If it is, then this problem is as good as finding pair for a given sum and while checking sum check for their (a^b == SUM) this should be enough and this problem can be solved in O(n).
URL

And you can't do better than that. In worst case you have to visit each element atleast once.

Cereal_Killer
  • 304
  • 2
  • 13