Source : Microsoft Interview Question
Given a sorted array, in which every element is present twice except one which is present single time
Do a binary "search" (rather traversal) on the array, check both neighbors, if both are different from the value in the middle, you have the solution. This is O(log n)
.
Yes, The array is sorted so we can apply binary search to find the single element. Let's see the pattern of occurrence of single element. Total number of elements will be always odd and single element occurs only at even index
Total number of elements 9, single elements always present at even index.
When (end_index - start_index) % 4 == 0
, The single element is occurring in middle.
if A[mid-1] == A[mid] --> single element left side
if A[mid] == A[mid+1] --> single element right side
Total number of elements 11, single elements always present at even index. When (end_index - start_index) % 4 != 0
, The single element is not occurring in middle.
if A[mid] == A[mid+1] --> single element left
if A[mid-1] == A[mid] --> single element right
Total number of elements 13, single elements always present at even index. When (end_index - start_index) % 4 == 0
, The single element is occurring at middle also.
if A[mid-1] == A[mid] --> single element left side
if A[mid] == A[mid+1] --> single element right side
Below is the Python Code:
class Solution:
def singleNonDuplicate(self, A):
"""
:type nums: List[int]
:rtype: int
"""
L = len(A)
def binarySearch(A, start, end):
if start == end:
return A[start]
if start < end:
mid = int(start + (end - start)/2)
if A[mid-1] < A[mid] < A[mid+1]:
return A[mid]
if end - start == 2:
if A[end] != A[end-1]:
return A[end]
if end - start == 2:
if A[start] != A[start+1]:
return A[start]
if A[mid] == A[mid+1]:
if int(end-start)%4 == 0:
return binarySearch(A, mid+2, end)
else:
return binarySearch(A, start, mid-1)
elif A[mid-1] == A[mid]:
if int(end - start)%4 == 0:
return binarySearch(A, start, mid-2)
else:
return binarySearch(A, mid+1, end)
return binarySearch(A, 0, L-1)
if __name__ == "__main__":
s = Solution()
A = [1,1,2,3,3,4,4,5,5,6,6]
r = s.singleNonDuplicate(A)
print(r)
Yes, you can use the sortedness to reduce the complexity to O(log n)
by doing a binary search.
Since the array is sorted, before the missing element, each value occupies the spots 2*k
and 2*k+1
in the array (assuming 0-based indexing).
So you go to the middle of the array, say index h
, and check either index h+1
if h
is even, or h-1
if h
is odd. If the missing element comes later, the values at these positions are equal, if it comes before, the values are different. Repeat until the missing element is located.