57

Accenture interview question:

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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
karank
  • 571
  • 1
  • 4
  • 6
  • 4
    What is a "pair" - can you give an example? I.e. is { 3, -3 } a pair, or is { 3, 3 } a pair? – GalacticCowboy Apr 15 '10 at 11:26
  • 4
    A pair is always two of the same kind. 3 and -3 is not a pair. – Lasse V. Karlsen Apr 15 '10 at 11:48
  • 3
    A pair is whatever a problem defines it to be. In this case, I think the question considers (x, -x) a pair and it asks to find the number that has no pair. Clarifications would be nice however. – IVlad Apr 15 '10 at 12:38
  • 1
    possible duplicate of http://stackoverflow.com/questions/1851716/algorithm-to-find-the-duplicate-numbers-in-an-array-fastest-way – starblue Apr 16 '10 at 18:20
  • 2
    This is a duplicate of http://stackoverflow.com/questions/35185/finding-a-single-number-in-a-list/35271#35271 – Kyle Cronin Apr 16 '10 at 21:37

11 Answers11

101

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
  • 445,704
  • 82
  • 492
  • 529
  • 1
    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 Apr 15 '10 at 10:00
  • 4
    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 Apr 15 '10 at 10:03
  • 18
    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 Apr 15 '10 at 12:51
  • 1
    The method "returns" (i.e. prints) `array[N-1]`, in your case `6` wich is the solution. – phimuemue Apr 15 '10 at 14:57
  • 1
    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 Apr 15 '10 at 15:31
  • 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. Apr 15 '10 at 17:05
  • I have a similar solution (using XOR) here http://stackoverflow.com/questions/35185/finding-a-single-number-in-a-list/35271#35271 – Kyle Cronin Apr 16 '10 at 21:38
  • If you're having trouble visualizing why the bits cancel out if paired even if not next to each other, imagine each bit represents a locker and each time you visit a bit, you flip the locker from open to closed or closed to open (that's a variation of this same interview question). When the same bit pattern is encountered twice, the net change is to open and close a locker. If encountered just once, that number's bit pattern will remain. – Sridhar Sarnobat May 30 '17 at 00:38
3

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
  • 3,167
  • 2
  • 25
  • 26
  • 1
    I hope the interviewer realizes that not everyone knows bitwise manipulation and will accept this answer even though it uses more space. – Sridhar Sarnobat May 30 '17 at 00:36
3

Single line Linq example with a XOR solution :

Demo on DotNetFiddle

public static void Main()
{
    int[] tab = { 1, 2, 3, 2, 1 };
    Console.WriteLine(GetSingle(tab));
}

private static int GetSingle(IEnumerable<int> tab)
{
    return tab.Aggregate(0, (current, i) => current ^ i);
}

For fun and profit

Edit:

Explication for this snippet.

var a = 2;
var b = 2;
Console.WriteLine(a ^ b); // will print 0
// because x ^ x == 0

var c = 3;
Console.WriteLine(a ^ b ^ c); // will print 3
// because 0 ^ x == x

Console.WriteLine(0 ^ a); // guess the output
// get it? :)
// Now, lets aggregate this enumerable ;)
aloisdg
  • 22,270
  • 6
  • 85
  • 105
  • I think there is some bug here. Please check array : { 2, 1, 2, 2, 1,1,5 } - code on the Demo on DotNetFiddle returns 6, while expected value should be 5 – lm. Jul 30 '15 at 09:58
  • No bug here. Your input is wrong. You have threefold instead of pair here :) – aloisdg Aug 24 '15 at 11:15
  • @aloisdg Do you mind explaining the theory behind the solution? I have tired it and it works but i want to understand how you knew XORing all the elements would result in the unpaired int. Thanks – Anwuna Jan 24 '16 at 18:35
  • @Anwuna I added a tiny snippet. The logic behind this should be appear by itself. – aloisdg Jan 30 '16 at 08:54
3

The best answer is the XOR operator. Just for fun another way is, if you are allowed to sort the array, to sort it and compare adjacent integers. This assumes all integers appear exactly twice with one integer appearing once.

// Random array of integers
int[] arr = {1, 2, 3, 4, 5, 6, 7, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9};

// Sort the array.
Arrays.sort(arr);

// Array now looks like: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 9 9 
// Cycle through array comparing adjacent values.
for(int i = 0; i < arr.length; i++){

    // This would mean the single number was the last element in the array.
    if(i == arr.length-1)
        singleNum = arr[i];

    // If the adjacent elements are the same, skip foward. 
    if(i < arr.length-1 && arr[i] == arr[i+1])
        i ++;
    else
        // Otherwise, you found the single number.
        singleNum = arr[i];
}
Michael Martin
  • 410
  • 4
  • 9
2

Perform XOR among all elements of the given array

def unpaired(arr):
    result = 0
    for i in arr:
        result = result^i
    return result
shashisp
  • 2,879
  • 7
  • 19
  • 29
  • How it solves the problem?? can you dry run a simple example. How XOR operator can be used for finding element which have no pair. – Pradeep Singh Jun 13 '17 at 10:03
1

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dave M
  • 1,302
  • 1
  • 16
  • 28
  • I just share [another Linq answer](http://stackoverflow.com/a/29352593/1248177). You might like it. – aloisdg Mar 30 '15 at 17:35
1

Best solution using JavaScript, took me some time.

    var singleNumber = function(nums) {
       return nums.reduce((a,b) => a^b);
    };

Using reduce, code will add all of the numbers cumulatively, but since the pars (a, b) using XOR cancel each other out, only the number without the par will be returned.

Bojan Tomić
  • 1,007
  • 12
  • 19
-1

It's a good solution too. In this example, we have one cycle passage.

function getUpaired(arr) {
    var obj = {};
    for (var i = 0; i < arr.length; i++) {
        if (typeof obj[arr[i]] !== 'undefined') {
            delete obj[arr[i]];
            continue;
        }
    obj[arr[i]] = i;
    }
    return Number(Object.keys(obj)[0]);
}
getUpaired([0,0,2,1,3,2,1]);
-1

If you are using Swift you can find unpaired element with following code

func findUnpaired(_ arr: [Int]) -> Int {
    return arr.reduce(0, +)
}
atalayasa
  • 3,310
  • 25
  • 42
-1

A java solution of the above question:

public int singleNumber(int[] nums) {
    int result = nums[0];
    for(int i = 1; i < nums.length; i++) {
        result = result^nums[i];
    }
    return result;
}
Pritam Banerjee
  • 17,953
  • 10
  • 93
  • 108
-1
public int solution(int[] A) {
  var NumericGroups = A.GroupBy(X=> X).Distinct();
  int UnpairedNumber=  NumericGroups.First(k => k.Count() <2).FirstOrDefault();
  eturn UnpairedNumber;
}
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
  • 1
    Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Apr 11 '23 at 09:36