I came across a post How to find a duplicate element in an array of shuffled consecutive integers? but later realized that this fails for many input.
For ex:
a
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];
}
printf("%d",j);
}
This code will give the output 605, as desired!
From original question:
Suppose you have an array of 1001 integers. The integers are in random order, but you know each of the integers is between 1 and 1000 (inclusive). In addition, each number appears only once in the array, except for one number, which occurs twice.
It basically says, that algorithm only works when you have consecutive integers, starting with 1, ending with some N.
If you want to modify it to more general case, you have to do following things:
Find minimum and maximum in array. Then calculate expected output (xor all integers between minimum and maximum). Then calculate xor of all elements in array. Then xor this two things and you get an output.
//There i have created the program to find out the duplicate element in array. Please edit if there are required some changes.
int main()
{
int arr[] = {601,602,603,604,605,605,606,607};
//int arr[] = {601,601,604,602,605,606,607};
int n= sizeof(arr)/sizeof(arr[0]);
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n; j++)
{
int res = arr[i] ^ arr[j];
if (res == 0)
{
std::cout<< "Repeated Element in array = "<<arr[i]<<std::endl;
}
}
}
return 0;
}
//OR You can use HashTable and Hash Function when you enter the same
value into the hash table that time you can make count if its greater than
one value at particular index of HashTable then you can say that there are repeated value in the array.
Although the answers provided here are good, yet I'd like you to refer the answer by Mohit Jain if there is an ambiguity.
The fact variable xor variable = zero
can be used to locate the duplicates present in the array precisely and easily. Hope that helps!
Remember these two properties of XOR operator :
(1) If you take xor of a number with 0 ( zero ) , it would return the same number again.
Means , n ^ 0 = n
(2) If you take xor of a number with itself , it would return 0 ( zero ).
Means , n ^ n = 0
Now , Coming to the problem :
Let Input_arr = { 23 , 21 , 24 , 27 , 22 , 27 , 26 , 25 }
Output should be 27 ( because 27 is the duplicate element in the Input_arr ).
Solution :
Step 1 : Find “min” and “max” value in the given array. It will take O(n).
Step 2 : Find XOR of all integers from range “min” to “max” ( inclusive ).
Step 3 : Find XOR of all elements of the given array.
Step 4 : XOR of Step 2 and Step 3 will give the required duplicate number.
Description :
Step1 : min = 21 , max = 27
Step 2 : Step2_result = 21 ^ 22 ^ 23 ^ 24 ^ 25 ^ 26 ^ 27 = 20
Step 3 : Step3_result = 23 ^ 21 ^ 24 ^ 27 ^ 22 ^ 27 ^ 26 ^ 25 = 15
Step 4 : Final_Result = Step2_result ^ Step3_result = 20 ^ 15 = 27
But , How Final_Result calculated the duplicate number ?
Final_Result = ( 21 ^ 22 ^ 23 ^ 24 ^ 25 ^ 26 ^ 27 ) ^ ( 23 ^ 21 ^ 24 ^ 27 ^ 22 ^ 27 ^ 26 ^ 25 )
Now , Remember above two properties : n ^ n = 0 AND n ^ 0 = n
So , here ,
Final_Result = ( 21 ^ 21 ) ^ ( 22 ^ 22 ) ^ ( 23 ^ 23 ) ^ ( 24 ^ 24 ) ^ ( 25 ^ 25 ) ^ ( 26 ^ 26 ) ^ ( 27 ^ 27 ^ 27 )
= 0 ^ 0 ^ 0 ^ 0 ^ 0 ^ 0 ^ ( 27 ^ 0 ) ( property applied )
= 0 ^ 27 ( because we know 0 ^ 0 = 0 )
= 27 ( Required Result )
Here is the code shown in the original question, which is different than your implementation. You have modified it to use a local variable instead of the last member of the array, that makes a difference:
for (int i = 1; i < 1001; i++)
{
array[i] = array[i] ^ array[i-1] ^ i;
}
printf("Answer : %d\n", array[1000]);