Find the two numbers with odd occurrences in an unsorted array - GeeksforGeeks

14 Feb, 2022
Given an unsorted array that contains even number of occurrences for all numbers except two numbers. Find the two numbers which have odd occurrences in O(n) time complexity and O(1) extra space.
Examples: 
Input: {12, 23, 34, 12, 12, 23, 12, 45}
Output: 34 and 45

Input: {4, 4, 100, 5000, 4, 4, 4, 4, 100, 100}
Output: 100 and 5000

Input: {10, 20}
Output: 10 and 20
A naive method to solve this problem is to run two nested loops. The outer loop picks an element and the inner loop counts the number of occurrences of the picked element. If the count of occurrences is odd then print the number. The time complexity of this method is O(n^2).
We can use sorting to get the odd occurring numbers in O(nLogn) time. First sort the numbers using an O(nLogn) sorting algorithm like Merge Sort, Heap Sort.. etc. Once the array is sorted, all we need to do is a linear scan of the array and print the odd occurring number. 
We can also use hashing. Create an empty hash table which will have elements and their counts. Pick all elements of input array one by one. Look for the picked element in hash table. If the element is found in hash table, increment its count in table. If the element is not found, then enter it in hash table with count as 1. After all elements are entered in hash table, scan the hash table and print elements with odd count. This approach may take O(n) time on average, but it requires O(n) extra space.
A O(n) time and O(1) extra space solution using XOR: Let the two odd occurring numbers be x and y. We use bitwise XOR to get x and y. We try to make 2 groups such that x and y go to different groups. E.g. [a, a, b, b, x], . Then the problem will become “Find ‘one’ number with odd occurrence in an unsorted array”, which becomes a simple problem and will be solved using XOR. Below are steps to group x and y differently.
1.    The first step is to do XOR of all elements present in array. XOR of all elements gives us XOR of x and y because of the following properties of XOR operation.         1) XOR of any number n with itself gives us 0, i.e., n ^ n = 0         2) XOR of any number n with 0 gives us n, i.e., n ^ 0 = n         3) XOR is cumulative and associative.
        So we have XOR of x and y after the first step, in decimal form. E.g. 5 ^ 6 returns 3, which is computed in bit form as 101 ^ 110 = 011. Let the ‘value’ of XOR be xor2. Every Set bit** in xor2 indicates that ‘the corresponding bits in x and y have values different from each other’ (XOR property- ‘1 when bits are different’). 
** ( Set-bits are 1’s in binary form. E.g. 101 has 2 set bits(1’s), at 0th index and at 2nd index. )
For example, if x = 6 (0110) and y = 15 (1111), then xor2 will be (1001), the two set bits in xor2 indicate that the corresponding bits in x and y are different, at 0th index and at 3rd index both. 
2.    In the second step, we pick a set bit of xor2. Idea is to use the fact that xor2 is ‘1’ in indexes where bits of x and y are different. So we separate x and y to different groups, along with rest of the numbers of list, based on whether the number has same set-bit or not.  
     We choose the rightmost set bit of xor2 as it is easy to get rightmost set bit of a number (bit magic). If we bitwise AND a number with its negative counterpart, we get rightmost set bit. (just an observation based property, do remember). So, (xor2) & (-xor2) will give us right set bit. Find (-number) by 2’s complement, that is ((1’s complement) +1 ). It can also be written as (~number)+1. 
   a)    Example of 2’s complement :
 7 is 00111(any no. of preceding zeroes). 1’s complement is obtained by flipping bits , 11000. Then add 1, so 2’s complement of 7 is 11001. Since first bit is 1, its a negative no. 
 (-1)*16 + 1*8 +1*1  =  -7
   b)    Example of (number) & (-number) = right set bit :
 Continuing example of 7,  7 is 00111 and -7 is 11001 , 7 & -7 is  00001. So, rightmost set bit of 7 is 1.
 Another example with 12 & -12:
 12 is 01100 ** and -12 is calculated by flipping digits and adding 1. So, 10011 and adding 1 gives 10100.  12 & -12,  01100 & 10100  gives  00100 as set bit, that is returned as 4 in decimal system, also referred as Set-bit Number here.
 ** (since number is 32 bit, there are 28 0’s left of ‘left set-bit’, but taking only a few is okay. Positive numbers have leftmost bit 0 and negative have 1 )
3.    In third step, we separate x and y in different groups : We now know that for selected set bit index, x and y have different corresponding bits. If we AND all numbers in list with set bit, some will give 0 and others will give 1. We will put all numbers giving zeroes in one group and ones in another. x and y will fall in different groups. 
Explained with example:-
E.g. arr = [4, 2, 4, 10, 2, 3, 3, 12] ,  
Step 1) XOR of all in arr will cancel all repeating nos. 10 ^12 will be ans. 1010 ^ 1100 will be 0110 that is xor=6. 
Step 2) Set bit is 10 from 0110 from visualization. (number) & (-number) is also a quick way to find right set bit.
            xor & (-xor) can be coded directly. 6 is 0110 and finding -6 by flipping digits and adding 1, 1001 +1 = 1010.
            So 6 AND -6 is essentially 0110 & 1010, that is 0010 i.e. 2 – Set-bit Number.
Step 3) AND of all in list with 2 (Set bit no.) will give us numbers that give either 1 or 0, and we make groups.
            [4, 4, 12] and [2, 10, 2, 3, 3], giving 0 and 1 respectively on AND with Set-bit number.
Step 4) XOR of 1st group will give us x=12, x ^ y is known from 1st step i.e. 6. x ^(x ^y) will give us y. 12 ^6 is 10.
           x=12, y=10
    This step works because of the same properties of XOR. All the occurrences of a number will go in same set. XOR of all occurrences of a number which occur even number of times will result in 0 in its set. And the xor of a set will be one of the odd occurring elements.  
C++
C
Java
Python3
C#
PHP
Javascript
// C++ Program to find the two odd occurring elements#include <bits/stdc++.h>using namespace std; /* Prints two numbers that occur odd number of times. Thefunction assumes that the array size is at least 2 andthere are exactly two numbers occurring odd number of times. */void printTwoOdd(int arr[], int size){    int xor2 = arr[0]; /* Will hold XOR of two odd occurring elements */    int set_bit_no; /* Will have only single set bit of xor2 */    int i;    int n = size - 2;    int x = 0, y = 0;         /* Get the xor of all elements in arr[]. The xor will basically        be xor of two odd occurring elements */    for(i = 1; i < size; i++)        xor2 = xor2 ^ arr[i];         /* Get one set bit in the xor2. We get rightmost set bit        in the following line as it is easy to get */    set_bit_no = xor2 & ~(xor2-1);         /* Now divide elements in two sets:        1) The elements having the corresponding bit as 1.        2) The elements having the corresponding bit as 0. */    for(i = 0; i < size; i++)    {        /* XOR of first set is finally going to hold one odd        occurring number x */        if(arr[i] & set_bit_no)        x = x ^ arr[i];             /* XOR of second set is finally going to hold the other        odd occurring number y */        else        y = y ^ arr[i];    }     cout << "The two ODD elements are " << x << " & " << y;} /* Driver code */int main(){    int arr[] = {4, 2, 4, 5, 2, 3, 3, 1};    int arr_size = sizeof(arr)/sizeof(arr[0]);    printTwoOdd(arr, arr_size);    return 0;} // This is code is contributed by rathbhupendra
// Program to find the two odd occurring elements#include<stdio.h> /* Prints two numbers that occur odd number of times. The   function assumes that the array size is at least 2 and   there are exactly two numbers occurring odd number of times. */void printTwoOdd(int arr[], int size){  int xor2 = arr[0]; /* Will hold XOR of two odd occurring elements */  int set_bit_no;  /* Will have only single set bit of xor2 */  int i;  int n = size - 2;  int x = 0, y = 0;   /* Get the xor of all elements in arr[]. The xor will basically     be xor of two odd occurring elements */  for(i = 1; i < size; i++)    xor2 = xor2 ^ arr[i];   /* Get one set bit in the xor2. We get rightmost set bit     in the following line as it is easy to get */  set_bit_no = xor2 & ~(xor2-1);   /* Now divide elements in two sets:    1) The elements having the corresponding bit as 1.    2) The elements having the corresponding bit as 0.  */  for(i = 0; i < size; i++)  {     /* XOR of first set is finally going to hold one odd       occurring number x */    if(arr[i] & set_bit_no)      x = x ^ arr[i];      /* XOR of second set is finally going to hold the other       odd occurring number y */    else      y = y ^ arr[i];  }   printf("\n The two ODD elements are %d & %d ", x, y);} /* Driver program to test above function */int main(){  int arr[] = {4, 2, 4, 5, 2, 3, 3, 1};  int arr_size = sizeof(arr)/sizeof(arr[0]);  printTwoOdd(arr, arr_size);  getchar();  return 0;}
// Java program to find two odd// occurring elements import java.util.*; class Main{            /* Prints two numbers that occur odd       number of times. The function assumes       that the array size is at least 2 and       there are exactly two numbers occurring       odd number of times. */    static void printTwoOdd(int arr[], int size)    {      /* Will hold XOR of two odd occurring elements */         int xor2 = arr[0];             /* Will have only single set bit of xor2 */      int set_bit_no;       int i;      int n = size - 2;      int x = 0, y = 0;            /* Get the xor of all elements in arr[].         The xor will basically be xor of two         odd occurring elements */      for(i = 1; i < size; i++)        xor2 = xor2 ^ arr[i];            /* Get one set bit in the xor2. We get         rightmost set bit in the following         line as it is easy to get */      set_bit_no = xor2 & ~(xor2-1);            /* Now divide elements in two sets:            1) The elements having the               corresponding bit as 1.            2) The elements having the               corresponding bit as 0.  */      for(i = 0; i < size; i++)      {         /* XOR of first set is finally going            to hold one odd occurring number x */        if((arr[i] & set_bit_no)>0)          x = x ^ arr[i];               /* XOR of second set is finally going            to hold the other odd occurring number y */        else          y = y ^ arr[i];      }            System.out.println("The two ODD elements are "+                                        x + " & " + y);    }         // main function    public static void main (String[] args)    {        int arr[] = {4, 2, 4, 5, 2, 3, 3, 1};        int arr_size = arr.length;        printTwoOdd(arr, arr_size);    }}
# Python3 program to find the# two odd occurring elements # Prints two numbers that occur odd# number of times. The function assumes# that the array size is at least 2 and# there are exactly two numbers occurring# odd number of times.def printTwoOdd(arr, size):         # Will hold XOR of two odd occurring elements    xor2 = arr[0]         # Will have only single set bit of xor2    set_bit_no = 0     n = size - 2    x, y = 0, 0     # Get the xor of all elements in arr[].    # The xor will basically be xor of two    # odd occurring elements    for i in range(1, size):        xor2 = xor2 ^ arr[i]     # Get one set bit in the xor2. We get    # rightmost set bit in the following    # line as it is easy to get    set_bit_no = xor2 & ~(xor2 - 1)     # Now divide elements in two sets:    # 1) The elements having the corresponding bit as 1.    # 2) The elements having the corresponding bit as 0.    for i in range(size):             # XOR of first set is finally going to         # hold one odd  occurring number x        if(arr[i] & set_bit_no):            x = x ^ arr[i]         # XOR of second set is finally going        # to hold the other odd occurring number y        else:            y = y ^ arr[i]     print("The two ODD elements are", x, "&", y) # Driver Codearr = [4, 2, 4, 5, 2, 3, 3, 1]arr_size = len(arr)printTwoOdd(arr, arr_size) # This code is contributed by Anant Agarwal.
// C# program to find two odd// occurring elementsusing System; class main{             // Prints two numbers that occur    // odd number of times. Function    // assumes that array size is at    // least 2 and there are exactly    // two numbers occurring odd number    // of times.    static void printTwoOdd(int []arr, int size) {          // Will hold XOR of two odd      //occurring elements        int xor2 = arr[0];              // Will have only single set      // bit of xor2      int set_bit_no;       int i;             //int n = size - 2;      int x = 0, y = 0;             // Get the xor of all the elements      // in arr[].The xor will basically      // be xor of two odd occurring      // elements      for(i = 1; i < size; i++)        xor2 = xor2 ^ arr[i];             // Get one set bit in the xor2.      // We get rightmost set bit in      // the following line as it is      // to get.         set_bit_no = xor2 & ~(xor2-1);             // divide elements in two sets:      // 1) The elements having the      // corresponding bit as 1.      // 2) The elements having the      // corresponding bit as 0.      for(i = 0; i < size; i++)      {         // XOR of first set is finally         // going to hold one odd         // occurring number x            if((arr[i] & set_bit_no)>0)            x = x ^ arr[i];                   // XOR of second set is finally            // going to hold the other            // odd occurring number y            else            y = y ^ arr[i];      }             Console.WriteLine("The two ODD elements are "+                                        x + " & " + y);    }          // main function    public static void Main()    {        int []arr = {4, 2, 4, 5, 2, 3, 3, 1};        int arr_size = arr.Length;        printTwoOdd(arr, arr_size);    }} //This code is contributed by Anant Agarwal.
<?php// PHP program to find the// two odd occurring elements /* Prints two numbers that occur   odd number of times. The   function assumes that the   array size is at least 2 and   there are exactly two numbers   occurring odd number of times. */function printTwoOdd($arr, $size){          // Will hold XOR of two     // odd occurring elements     $xor2 = $arr[0];           // Will have only single     // set bit of xor2     $set_bit_no;          $i;    $n = $size - 2;    $x = 0;$y = 0;      // Get the xor of all elements     // in arr[]. The xor will basically     // be xor of two odd occurring     // elements    for($i = 1; $i < $size; $i++)        $xor2 = $xor2 ^ $arr[$i];         // Get one set bit in the xor2.    // We get rightmost set bit    // in the following line as    // it is easy to get    $set_bit_no = $xor2 & ~($xor2-1);         /* Now divide elements in two sets:        1) The elements having the           corresponding bit as 1.        2) The elements having the           corresponding bit as 0. */    for($i = 0; $i < $size; $i++)    {                 /* XOR of first set is finally           going to hold one odd           occurring number x */        if($arr[$i] & $set_bit_no)        $x = $x ^ $arr[$i];             /* XOR of second set is finally           going to hold the other           odd occurring number y */        else        $y = $y ^ $arr[$i];    }         echo "The two ODD elements are ", $x, " & ", $y;    } // Driver Code$arr = array(4, 2, 4, 5, 2, 3, 3, 1);$arr_size = sizeof($arr);printTwoOdd($arr, $arr_size); // This code is Contributed by Ajit?>
<script> // Javascript program to find two odd// occurring elements // Prints two numbers that occur// odd number of times. Function// assumes that array size is at// least 2 and there are exactly// two numbers occurring odd number// of times.function printTwoOdd(arr, size){      // Will hold XOR of two odd    //occurring elements      let xor2 = arr[0];         // Will have only single set    // bit of xor2    let set_bit_no;     let i;         //int n = size - 2;    let x = 0, y = 0;         // Get the xor of all the elements    // in arr[].The xor will basically    // be xor of two odd occurring    // elements    for(i = 1; i < size; i++)        xor2 = xor2 ^ arr[i];         // Get one set bit in the xor2.    // We get rightmost set bit in    // the following line as it is    // to get.    set_bit_no = xor2 & ~(xor2-1);         // divide elements in two sets:    // 1) The elements having the    // corresponding bit as 1.    // 2) The elements having the    // corresponding bit as 0.    for(i = 0; i < size; i++)    {        // XOR of first set is finally        // going to hold one odd        // occurring number x        if ((arr[i] & set_bit_no)>0)            x = x ^ arr[i];                 // XOR of second set is finally        // going to hold the other        // odd occurring number y        else            y = y ^ arr[i];    }    document.write("The two ODD elements are "+ x +                   " & " + y + "</br>");} // Driver codelet arr = [ 4, 2, 4, 5, 2, 3, 3, 1 ];let arr_size = arr.length; printTwoOdd(arr, arr_size); // This code is contributed by divyesh072019 </script>
The two ODD elements are 5 & 1
Time Complexity: O(n) Auxiliary Space: O(1) 
Another solution would be using map O(n) time and O(n) extra space solution :
The extra space O(n) can be minimized to O(1) by directly taking inputs in map instead of array.
The idea is explained below using comments in code-
C++
Java
Python3
C#
Javascript
// C++ Program to find the two odd occurring elements#include <bits/stdc++.h>using namespace std; /* Prints two numbers that occur odd number of times. Thefunction assumes that the array size is at least 2 andthere are exactly two numbers occurring odd number of times.*/ void printTwoOdd(int arr[], int size){    /*Create map and calculate frequency of array of     * elements using array.*/     unordered_map<int, int> m;    for (int i = 0; i < size; i++) {        m[arr[i]]++;    }     /*Traverse through the map and check if its second      element that is the frequency is odd or not.Then this      is the odd occurring element .Its is clearly mentioned      in problem that there are only two odd occurring      elements so this will print those two elements.*/     cout << "The two ODD elements are ";    for (auto& x : m) {        if (x.second % 2 != 0)            cout << x.first << ", ";    }} /* Driver code */int main(){    int arr[] = { 4, 2, 4, 5, 2, 3, 3, 1 };    int arr_size = sizeof(arr) / sizeof(arr[0]);    printTwoOdd(arr, arr_size);    return 0;} // This is code is contributed by Abhishek
// Java Program to find the two odd occurring elements import java.util.*; class GFG{ /* Prints two numbers that occur odd number of times. Thefunction assumes that the array size is at least 2 andthere are exactly two numbers occurring odd number of times.*/ static void printTwoOdd(int arr[], int size){    /*Create map and calculate frequency of array of     * elements using array.*/     HashMap<Integer,Integer> m = new HashMap<Integer,Integer>();    for (int i = 0; i < size; i++) {         if(m.containsKey(arr[i])){                m.put(arr[i], m.get(arr[i])+1);            }            else{                m.put(arr[i], 1);            }    }     /*Traverse through the map and check if its second      element that is the frequency is odd or not.Then this      is the odd occurring element .Its is clearly mentioned      in problem that there are only two odd occurring      elements so this will print those two elements.*/     System.out.print("The two ODD elements are ");    for (Map.Entry<Integer,Integer> x : m.entrySet()) {        if (x.getValue() % 2 != 0)            System.out.print(x.getKey()+ ", ");    }} /* Driver code */public static void main(String[] args){    int arr[] = { 4, 2, 4, 5, 2, 3, 3, 1 };    int arr_size = arr.length;    printTwoOdd(arr, arr_size);}}  // This code is contributed by 29AjayKumar
# Python3 program to find the two odd occurring elements """ Prints two numbers that occur odd number of times.The function assumes that the array size is at least 2and there are exactly two numbers occurring odd numberof times."""def printTwoOdd(arr, size):    arr.sort()         # Create map and calculate frequency of array    # of elements using array.    m = {}    for i in range(size):        if arr[i] not in m:            m[arr[i]] = 0                     m[arr[i]] += 1         """Traverse through the map and check if its second    element that is the frequency is odd or not.Then this    is the odd occurring element .Its is clearly mentioned    in problem that there are only two odd occurring    elements so this will print those two elements."""    print("The two ODD elements are ", end = "")    for x in m:        if (m[x] % 2 != 0):            print(x, end = ", ")             # Driver codearr = [ 4, 2, 4, 5, 2, 3, 3, 1 ]arr_size = len(arr) printTwoOdd(arr, arr_size) # This code is contributed by shubhamsingh10
// C# program for the above approachusing System;using System.Collections.Generic;using System.Linq; public class GFG {     /* Prints two numbers that occur odd number of times. Thefunction assumes that the array size is at least 2 andthere are exactly two numbers occurring odd number of times.*/static void printTwoOdd(int[] arr, int size){    /*Create map and calculate frequency of array of     * elements using array.*/     Dictionary<int, int> m = new Dictionary<int, int>();     for (int i = 0; i < size; i++)        {            if (m.ContainsKey(arr[i]))                m[arr[i]]++;            else                m.Add(arr[i], 1);        }     /*Traverse through the map and check if its second      element that is the frequency is odd or not.Then this      is the odd occurring element .Its is clearly mentioned      in problem that there are only two odd occurring      elements so this will print those two elements.*/     Console.Write("The two ODD elements are ");    foreach (int x in m.Keys.ToList()){        if (m[x] % 2 != 0)            Console.Write(x + ", ");    }} // Driver Codepublic static void Main (string[] args) {         int[] arr = { 4, 2, 4, 5, 2, 3, 3, 1 };    int arr_size = arr.Length;    printTwoOdd(arr, arr_size);}} //  This code is contributed by splevel62.
<script> // JavaScript Program to find the two odd occurring elements /* Prints two numbers that occur odd number of times. Thefunction assumes that the array size is at least 2 andthere are exactly two numbers occurring odd number of times.*/ function printTwoOdd(arr, size){    /*Create map and calculate frequency of array of     * elements using array.*/     let m = new Map();    for (let i = 0; i < size; i++) {        if(m.has(arr[i])){            m.set(arr[i], m.get(arr[i]) + 1)        }else{            m.set(arr[i], 1)        }    }     /*Traverse through the map and check if its second      element that is the frequency is odd or not.Then this      is the odd occurring element .Its is clearly mentioned      in problem that there are only two odd occurring      elements so this will print those two elements.*/     document.write("The two ODD elements are ");    let ar = []    for (let x of m) {        if (x[1] % 2 != 0)            ar.push(x[0])    }    document.write(`${ar.reverse()},`)} /* Driver code */     let arr = [ 4, 2, 4, 5, 2, 3, 3, 1 ];    let arr_size = arr.length;    printTwoOdd(arr, arr_size); // This is code is contributed by gfgking </script>
The two ODD elements are 1, 5, 
 Time Complexity: O(n)
 Auxiliary Space: O(n)
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
jit_t
rathbhupendra
divyesh072019
abhishekcs001
gfgking
surinderdawra388
SHUBHAMSINGH10
aniketkumar20
splevel62
29AjayKumar
RohanTiwari
simmytarika5
Amazon
Bitwise-XOR
Operators
Arrays
Amazon
Arrays
Operators
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Stack Data Structure (Introduction and Program)
Top 50 Array Coding Problems for Interviews
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
Linked List vs Array
Python | Using 2D arrays/lists the right way
Maximum and minimum of an array using minimum number of comparisons
Given an array of size n and a number k, find all elements that appear more than n/k times
Queue | Set 1 (Introduction and Array Implementation)