views:

1134

answers:

5

You have been given an array of size 2n+1 that have n pair of integers(can be +ve, -ve or 0) and one unpaired element.

How would you find the unpaired element.

Pair means duplicate. So (3,3) is a pair and (3,-3) is not a pair.

+43  A: 

Take XOR of all the elements.

The pairs will cancel out as

a XOR a = 0

and the result will be the only unpaired element as

0 XOR a = a

If its okay to destroy the array you can XOR adjacent elements. Once done the last element of the array has the unpaired element:

N = Num of elements in array.
for( i=1 to N )
   arr[i] ^= arr[i-1];    
print arr[N-1]

If its not okay to destroy the array, you can make use of a variable to hold the result:

N = Num of elements in array.
Unpaired = arr[0];
for( i=1 to N )
   Unpaired = Unpaired ^ arr[i];    
print Unpaired

C function to do the same:

int findUnpaired(int *arr,int len) {
 int i;                  // loop counter.
 int unpaired;           // to hold the unpaired element.

 unpaired = arr[0];      // initialize it with the 1st array ele.

 for(i=1;i<len;i++) {    // loop for all remaining elements.
    unpaired ^= arr[i];  // XOR each element with the running XOR.
 }
 return unpaired;        // return result.
}
codaddict
the elements are not sorted, so copy elements will not be next to each other. My thinking it will work only when sorted. Correct?
karank
Not Correct. The elements need not be sorted. Take for example: 1 2 3 1 3. Trace the algorithm on this example. When you XOR all, you'll get 2.
codaddict
In formal terms, xor is commutative and associative, meaning that the order in which initial inputs are xored has no bearing on the final result.
Michał Marczyk
The method "returns" (i.e. prints) `array[N-1]`, in your case `6` wich is the solution.
phimuemue
Thanks phimuemue. I had to read unicornaddicts code a few time before I realised what it was doing. I've removed my comment.
Matt Ellen
I must admit I'm pretty impressed by the number of votes such a simple problem/solution yields. Here is a similar question (though not a duplicate): http://stackoverflow.com/questions/2605766/how-to-find-a-duplicate-element-in-an-array-of-shuffled-consecutive-integers/2606065. It seems the xor trick is pretty by interviews...
Matthieu M.
I have a similar solution (using XOR) here http://stackoverflow.com/questions/35185/finding-a-single-number-in-a-list/35271#35271
Kyle Cronin
A: 

A simpler method would be to add all the numbers. While adding change the sign of the one of the numbers in the pair, so that the pair sum becomes 0.

O(n) time and O(1) space.

Coder
..... WHAT?????
polygenelubricants
If the array isn't sorted, how do you know when you're adding a member of a pair that's already in your sum? i.e., how would you handle 1 2 3 1 3?
mtrw
Look poly and mtrw: I know it can be hard to understand, but to make the things very clear I'll trace it for you. 1 + 2 + 3 + (-1) + (-3) = 2. Which is the answer we want. I hope you get. Feel free to ask more questions.
Coder
How do you know when you get to the 2nd instance of `1`?
mtrw
http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html
Luc M
I think this might work IF there are only positive numbers (which the problem states is not the case) AND IF you keep a record as you go of which numbers you've already added. But if you do that, then it's no longer O(1) space, and you might as well just remove things from the list when you encounter them again because then there is no need for the running sum. Unless there's a chance of getting duplicate pairs (i.e. FOUR of the same number). Then you might be in trouble.
MatrixFrog
+1  A: 

Here'a a simple linq solution that can easily be extended to provide the number of occurrences of each unique element:

     int[] numbers = { -1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1 };

     var numberGroups =
         from n in numbers
         group n by n into g
         select new { Number = g.Key, IsPaired = g.Count() == 2 };

     Console.WriteLine("Unpaired elements:");
     foreach (var group in numberGroups)
     {
        if (!group.IsPaired)
           Console.WriteLine(group.Number);
     }

Output:

Unpaired elements: -1 0 5

Dave M
A: 

Alternate solution, to find all unique values in O(n) and O(n) space:

Initialize a Hash table.
For each value in the array, check if the value exists in the Hash table, if it does, remove it, if it doesn't, add it.
Return value is all the items inside the Hash table.

Can easily be modified to use a dictionary if the recurring values can recur more than once.

Rubys
A: 

Take the sum of all the elements.