Find the two repeating elements in a given array June 9, 2010 You are given an array of n+2 elements. All elements of the array are in range 1 to n. And all elements occur once except two numbers which occur twice. Find the two repeating numbers. For example, array = {4, 2, 4, 5, 2, 3, 1} and n = 5 The above array has n + 2 = 7 elements with all elements occurring once except 2 and 4 which occur twice. So the output should be 4 2. Method 1 (Basic) Use two loops. In the outer loop, pick elements one by one and count the number of occurrences of the picked element in the inner loop. This method doesn’t use the other useful data provided in questions like range of numbers is between 1 to n and there are only two repeating elements. void printRepeating( int arr[], int size) |
printf ( " Repeating elements are " ); |
int arr[] = {4, 2, 4, 5, 2, 3, 1}; |
int arr_size = sizeof (arr)/ sizeof (arr[0]); |
printRepeating(arr, arr_size); |
Time Complexity: O(n*n) Auxiliary Space: O(1) Method 2 (Use Count array) Traverse the array once. While traversing, keep track of count of all elements in the array using a temp array count[] of size n, when you see an element whose count is already set, print it as duplicate. This method uses the range given in the question to restrict the size of count[], but doesn’t use the data that there are only two repeating elements. void printRepeating( int arr[], int size) |
int *count = ( int *) calloc ( sizeof ( int ), (size - 2)); |
printf ( " Repeating elements are " ); |
int arr[] = {4, 2, 4, 5, 2, 3, 1}; |
int arr_size = sizeof (arr)/ sizeof (arr[0]); |
printRepeating(arr, arr_size); |
Time Complexity: O(n) Auxiliary Space: O(n) Method 3 (Make two equations) We have to find two numbers, so to unknowns. We know the sum of n numbers is n(n+1)/2 and product is n!. Make two equations using these sum and product formulas, and get values of two unknowns using the two equations. Let summation of all numbers in array be S and product be P Let the numbers which are being repeated are X and Y. X + Y = S – n(n+1)/2 XY = P/n! Using above two equations, we can find out X and Y. For array = 4 2 4 5 2 3 1, we get S = 21 and P as 960. X + Y = 21 – 15 = 6 XY = 960/5! = 8 X – Y = sqrt((X+Y)^2 – 4*XY) = sqrt(4) = 2 Using below two equations, we easily get X = (6 + 2)/2 and Y = (6-2)/2 X + Y = 6 X – Y = 2 Thanks to geek4u for suggesting this method. As pointed by Beginer , there can be addition and multiplication overflow problem with this approach. The methods 3 and 4 use all useful information given in the question void printRepeating( int arr[], int size) |
printf ( "The two Repeating elements are %d & %d" , x, y); |
return (n == 0)? 1 : n*fact(n-1); |
int arr[] = {4, 2, 4, 5, 2, 3, 1}; |
int arr_size = sizeof (arr)/ sizeof (arr[0]); |
printRepeating(arr, arr_size); |
Time Complexity: O(n) Auxiliary Space: O(1) Method 4 (Use XOR) Thanks to neophyte for suggesting this method. The approach used here is similar to method 2 of this post. Let the repeating numbers be X and Y, if we xor all the elements in the array and all integers from 1 to n, then the result is X xor Y. The 1’s in binary representation of X xor Y is corresponding to the different bits between X and Y. Suppose that the kth bit of X xor Y is 1, we can xor all the elements in the array and all integers from 1 to n, whose kth bits are 1. The result will be one of X and Y. void printRepeating( int arr[], int size) |
set_bit_no = xor & ~(xor-1); |
printf ( "\n The two repeating elements are %d & %d " , x, y); |
int arr[] = {4, 2, 4, 5, 2, 3, 1}; |
int arr_size = sizeof (arr)/ sizeof (arr[0]); |
printRepeating(arr, arr_size); |
Method 5 (Use array elements as index) Thanks to Manish K. Aasawat for suggesting this method. traverse the list for i= 1st to n+2 elements { check for sign of A[abs(A[i])] ; if positive then make it negative by A[abs(A[i])]=-A[abs(A[i])]; else // i.e., A[abs(A[i])] is negative this element (ith element of list) is a repetition }
Example: A[] = {1,1,2,3,2} i=1 ; A[abs(A[1])] i.e,A[1] is positive ; so make it negative ; so list now is {-1,1,2,3,2} i=2 ; A[abs(A[2])] i.e., A[1] is negative ; so A[i] i.e., A[2] is repetition, now list is {-1,1,2,3,2} i=3 ; list now becomes {-1,-1,2,3,2} and A[3] is not repeated now list becomes {-1,-1,-2,3,2} i=4 ; and A[4]=3 is not repeated i=5 ; we find A[abs(A[i])] = A[2] is negative so A[i]= 2 is a repetition, This method modifies the original array. void printRepeating( int arr[], int size) |
printf ( "\n The repeating elements are" ); |
arr[ abs (arr[i])] = -arr[ abs (arr[i])]; |
printf ( " %d " , abs (arr[i])); |
int arr[] = {1, 3, 2, 2, 1}; |
int arr_size = sizeof (arr)/ sizeof (arr[0]); |
printRepeating(arr, arr_size); |
The problem can be solved in linear time using other method also |