14

Possible Duplicate:
Finding a single number in a list

Given an array of numbers, except for one number all the others, occur twice. What should be the algorithm to find that number which occurs only once in the array?

Example

a[1..n] = [1,2,3,4,3,1,2] 

should return 4

Community
  • 1
  • 1
Gilles Simons
  • 143
  • 1
  • 1
  • 4

6 Answers6

24

Let the number which occurs only once in the array be x

x <- a[1]
for i <- 2 to n
   x <- x ^ a[i]
return x

Since a ^ a = 0 and a ^ 0 = a

Numbers which occur in pair cancel out and the result gets stored in x

Working code in C++

#include <iostream>

template<typename T, size_t N>
size_t size(T(&a)[N])
{
    return N;
}
int main()
{
   int a [] = {1,2,3,4,3,1,2};
   int x = a[0];
   for (size_t i = 1; i< size(a) ; ++i)
   {
      x = x ^ a[i];
   }
   std::cout << x;
} 
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
19
  1. Create new int i = 0
  2. XOR each item with i
  3. After all iterations there will be expected number in i
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • 1
    O__O may I ask how this solution was so obvious to everyone here?!! I couldn't have thought of it in days... – user541686 Jan 23 '11 at 06:27
  • @Mehrdad: don't know. Because it is trivia issue? – zerkms Jan 23 '11 at 06:29
  • @zerkms: Did you mean trivia or trivial? Either way, though... any recommendations on how to learn to think of solutions to problems like this that you haven't seen before? (I guess you need to be clever... not sure I'm that clever though. :( ) – user541686 Jan 23 '11 at 06:34
  • 2
    @Mehrdad: This question appears over and over. It's a bit of programming lore and one of those "aha!" moments the first time you see it. – Blastfurnace Jan 23 '11 at 06:40
  • 1
    @zerkms: I swear I could've lived my entire life programming without knowing this fact... @Blastfurnace: Yeah, it definitely was :) – user541686 Jan 23 '11 at 06:56
  • @Mehrdad: Most people here are most likely copying other answers to some an extent, possibly without realizing it. It's a phenomenon that happens frequently on the internet. Ralph Waldo Emerson once said, and I'm paraphrasing, that the recognition of genius is like remembering an old rejected thought you once had. When someone sees something particularly clever but simple, there's a tendency to immediately "own" it and take it as one's own, resulting in lots of duplicate answers in forums like this. – Zach Conn Dec 18 '12 at 01:47
2

If you have quantities which cannot be reasonably xored (Big Integers or numbers represented as Strings, for example), an alternate approach which is also O(n) time, (but O(n) space rather than O(1) space) would be to simply use a hash table. The algorithm looks like:

Create a hash table of the same size as the list
For every item in the list:
     If item is a key in hash table
         then remove item from hash table
         else add item to hash table with nominal value
At the end, there should be exactly one item in the hash table

I would do, C or C++ code, but neither of them have hash tables built in. (Don't ask me why C++ doesn't have a hash table in the STL, but does have a hash map based on a red-black tree, because I have no idea what they were thinking.) And, unfortunately, I don't have a C# compiler handy to test for syntax errors, so I'm giving you Java code. It's pretty similar, though.

import java.util.Hashtable;
import java.util.List;

class FindUnique {
    public static <T> T findUnique(List<T> list) {
        Hashtable<T,Character> ht = new Hashtable<T,Character>(list.size());
        for (T item : list) {
            if (ht.containsKey(item)) {
                ht.remove(item);
            } else {
                ht.put(item,'x');
            }
        }
        return ht.keys().nextElement();
    }
}
Keith Irwin
  • 5,628
  • 22
  • 31
  • Hashed containers are in the upcoming C++0x as `std::unordered_set` and `std::unordered_map`. Current compilers already have these as TR1 library extensions. – Blastfurnace Jan 23 '11 at 16:13
  • For the sake of completeness, though not part of core language, if you are on a POSIX system hcreate / hsearch is available http://linux.die.net/man/3/hsearch – fkl Oct 31 '14 at 20:53
1

Well i only know of the Brute force algo and it is to traverse whole array and check

Code will be like (in C#):

k=0;
for(int i=0 ; i < array.Length ; i++)
{
    k ^= array[i];
}
return k;
Shekhar_Pro
  • 18,056
  • 9
  • 55
  • 79
1

zerkms' answer in C++

int a[] = { 1,2,3,4,3,1,2 };

int i = std::accumulate(a, a + 7, 0, std::bit_xor<int>());
Blastfurnace
  • 18,411
  • 56
  • 55
  • 70
0

You could sort the array and then find the first element that doesn't have a pair. That would require several loops for sorting and a loop for finding the single element.

But a simplier method would be setting the double keys to zero or a value that is not possible in the current format. Depends on the programming language, as well, as you cannot change key types in c++ unlike c#.

Vlad
  • 165
  • 5
  • Several O(n) solutions based on XOR have been posted yet – Dr. belisarius Jan 23 '11 at 06:19
  • There isn't a way of determining if there's been an answer posted without reloading the page. But it's your truth. – Vlad Jan 23 '11 at 06:32
  • actually there is a way. While you're writing an answer and one more answer has been posted - you should see a bar on the top about new one with button to load them to the current page (without reloading). – zerkms Jan 23 '11 at 06:37
  • 1
    I'm beginning to suspect that not only the iPad crops code snippets overflow, but doesn't load that bar as well. Thanks for the tip! – Vlad Jan 23 '11 at 06:50