Find the element that appears once in a sorted array - GeeksforGeeks
Given a sorted array in which all elements appear twice (one after one) and one element appears only once. Find that element in O(log n) complexity.
Example:
https://solvethat.wordpress.com/2013/10/21/find-the-only-one-non-repeating-value-in-a-sorted-array/
Read full article from Find the element that appears once in a sorted array - GeeksforGeeks
Given a sorted array in which all elements appear twice (one after one) and one element appears only once. Find that element in O(log n) complexity.
Example:
Input: arr[] = {1, 1, 3, 3, 4, 5, 5, 7, 7, 8, 8} Output: 4
Input: arr[] = {1, 1, 3, 3, 4, 4, 5, 5, 7, 7, 8} Output: 8
An Efficient Solution can find the required element in O(Log n) time. The idea is to use Binary Search. Below is an observation in input array.
All elements before the required have first occurrence at even index (0, 2, ..) and next occurrence at odd index (1, 3, …). And all elements after the required element have first occurrence at odd index and next occurrence at even index.
All elements before the required have first occurrence at even index (0, 2, ..) and next occurrence at odd index (1, 3, …). And all elements after the required element have first occurrence at odd index and next occurrence at even index.
1) Find the middle index, say ‘mid’.
2) If ‘mid’ is even, then compare arr[mid] and arr[mid + 1]. If both are same, then the required element after ‘mid’ else before mid.
3) If ‘mid’ is odd, then compare arr[mid] and arr[mid – 1]. If both are same, then the required element after ‘mid’ else before mid.
// A Binary Search based function to find the element
// that appears only once
void
search(
int
*arr,
int
low,
int
high)
{
// Base cases
if
(low > high)
return
;
if
(low==high)
{
printf
(
"The required element is %d "
, arr[low]);
return
;
}
// Find the middle point
int
mid = (low + high) / 2;
// If mid is even and element next to mid is
// same as mid, then output element lies on
// right side, else on left side
if
(mid%2 == 0)
{
if
(arr[mid] == arr[mid+1])
search(arr, mid+2, high);
else
search(arr, low, mid);
}
else
// If mid is odd
{
if
(arr[mid] == arr[mid-1])
search(arr, mid-2, high);
else
search(arr, low, mid-1);
}
}
As we have just identified the properties, we can see that the non repeating number is located in the odd-size part of the array. The binary search always divides the search space into two pieces. Dividing an odd size space, gives two subspaces – one of the even size, and the second one of the odd size.
Unfortunately, dividing the array into two subarrays doesn’t give as any information which half is the odd size, and which is the even size. But we can divide the array arbitrary, so that the first half is always even size. Then comparing the last element L of the left subarray to the first element R of the right subarray, is sufficient to establish, in which half the extra element is located. If L != R then we need to check the second half of the array, otherwise the left one.
int
findOneElement(
int
array[],
int
size)
{
if
(size == 1)
return
array[0];
int
medium = size/2;
// make the size even number
medium = medium % 2 == 0 ? medium : medium + 1;
if
(array == array) //?
{
// look in the left subarray
return
findOneElement(array, medium - 1);
}
else
{
// look in the right subarray
return
findOneElement(array + medium + 1, size - (medium + 1));
}
}