For a more general version of this problem (without these silly restrictions):
You can do this in O (n) time and in O (1) space without any restrictions or iteration over all bits and using only O (1) time bit manipulations, such as the XOR trick that worked on 2 missing numbers .
Here is the (pseudo) code to find only one of the numbers:
// Given an array arr with 2k+3 numbers, k of which are repeated twice // and the remaining three are distinct: a,b,c. // returns one of a,b,c. int FindUnique(int []arr) { int s = 0; // This will ultimately hold a ^ b ^ c (bitwise XOR) for (int i = 0; i < arr.Length; i++) { s ^= arr[i]; } int d = 0; // this holds diff(a,s) ^ diff(b,s) ^ diff(c,s) for (int i = 0; i < arr.Length; i++) { d ^= diff(arr[i],s); } int e = lowestBit(d); // This gives the position where one of a,b,c differs // from the others. int bucket1 = 0; int bucket2 = 0; for (int i = 0; i < arr.Length; i++) { if (arr[i] & e) { bucket1 ^= arr[i]; } else { bucket2 ^= arr[i]; } } int count1 = 0; int count2 = 0; for (int i = 0; i < arr.Length; i++) { if (arr[i] == bucket1) { count1++; } if (arr[i] == bucket2) { count2++; } } if (count1 == 1) return bucket1; return bucket2; } // return a number with the lowest bit of x ^ s set to 1 and rest 0. // ie the lowest bit position where x and s differ. int diff(int x, int s) { return lowestBit(x ^ s); } // Returns a number with only the lowest bit of y set. int lowestBit(int y) { return y & ~(y-1); }
The idea is this:
Say the numbers that appear once: a, b, c.
Now run XOR through the array to get s = a XOR b XOR c.
Since the numbers are different, note that s cannot be a or b or c (since the other two will be equal then), so there is at least one bit (not necessarily in the same position), where each of a, b , c is different from s.
In the case of two numbers, we could see that s is non-zero and selects the bit that distinguished a and b and worked with it.
We encounter difficulties when we have three numbers, but we can still find a little to distinguish one of the numbers.
For each number x, find the least significant bit that is different from s. Consider a binary number in which only this bit is set to one, and the rest are zero. Name this number diff (x).
Now, if we calculate diff (x) for each number and XOR them together, we get d = diff (a) XOR diff (b) XOR diff (c).
Note that d cannot be null.
Now find the least significant bit of bit d. This bit position can be used to unload one of a, b, c, since not all of a, b, c can have the same bit in this position: if they did, then this bit s, which is the XOR of these three should be the same, but we guaranteed that we chose this bit s to be different from at least one of the corresponding bits in a, b, c.
So, we again XOR, differentiate on this bit and check which of the two resulting numbers appears exactly once in the array. Once we find one number, we know how to deal with two numbers.
To find diff, just use bithack: x & ~(x-1)
, which is a standard bit hack and can be considered O (1) (instead of O (number of bits)).