Friday, September 28, 2012

Using XOR operator for finding duplicate element

A XOR statement has the property that 'a' XOR 'a' will always be 0, that is they cancel out, thus, if you know that your list has only one duplicate and that the range is say x to y, 601 to 607 in your case, it is feasible to keep the xor of all elements from x to y in a variable, and then xor this variable with all the elements you have in your array. Since there will be only one element which will be duplicated it will not be cancelled out due to xor operation and that will be your answer.

void main()
{
    int a[8]={601,602,603,604,605,605,606,607};
    int k,i,j=601;

    for(i=602;i<=607;i++)
    {
        j=j^i;
    }

    for(k=0; k<8; k++)
    {
        j = j^a[k];
    }
    // j = duplicate element
}

Variation:
An array of 2 elements - one element occurs even number of times & the other odd number of times. How would you find the value that occurs odd number of times ?

Get all the unique numbers in the array using a set in O(N) time. Then we XOR the original array and the unique numbers all together. Result of XOR is the even occurring element. Because every odd occurring element in the array will be XORed with itself odd number of times, therefore producing a 0. And the only even occurring element will be XORed with itself even number of times, which is the number itself.

Reason:  
XOR a number with itself odd number of times we get 0,.
XOR a number with itself even number of times then we get the number itself.

You are given an array of integers and a sum. Find all pairs of integers that equal that sum. Assume you have some sort of data structures that will be able to store the pairs. Write an algorithm to find all these pairs


Solution1
O(n^2) solution - Have two for loops

Solution2
Using a hashMap

Solution3
Most efficient - as no extra storage like hashMap

Sort the array

Two pointer - one to the begining and the other to the end of the array.

Compare the values pointed by the pointers untill the pointers collide
If the sum is lesser than m then increment the left pointer by one
If the sum is greater than m then decrement the right pointer by one
If the sum is equal to m then return "YES"