You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once.
Return the single element that appears only once.
Your solution must run in O(log n) time and O(1) space.
Example 1:
Input: nums = [1,1,2,3,3,4,4,8,8]
Output: 2Example 2:
Input: nums = [3,3,7,7,10,11,11]
Output: 10Constraints:
1 <= nums.length <= 1,00,000.0 <= nums[i] <= 1,00,000The simplest approach is to scan the array and check each element against its neighbors. If an element is different from both its left and right neighbors, it must be the single element. This works because every other element appears exactly twice and must be adjacent to its duplicate in a sorted array.
i.XOR has a useful property: a number XORed with itself gives 0, and a number XORed with 0 gives the number itself. Since every element except one appears twice, XORing all elements together will cancel out all pairs, leaving only the single element.
xorr to 0.xorr.xorr, which now holds the single non-duplicate element.Since the array is sorted and every element except one appears twice, we can use binary search. Before the single element, pairs start at even indices (0, 2, 4...). After the single element, this pattern shifts. By checking whether the middle element pairs correctly with its neighbor, we can determine which half contains the single element.
l and r at the start and end of the array.l <= r:m.nums[m] differs from both neighbors, return nums[m].m).r to m - 1.l to m + 1.class Solution:
def singleNonDuplicate(self, nums: List[int]) -> int:
l, r = 0, len(nums) - 1
while l <= r:
m = l + ((r - l) // 2)
if ((m - 1 < 0 or nums[m - 1] != nums[m]) and
(m + 1 == len(nums) or nums[m] != nums[m + 1])):
return nums[m]
leftSize = m - 1 if nums[m - 1] == nums[m] else m
if leftSize % 2:
r = m - 1
else:
l = m + 1We can simplify binary search by only considering even indices. In a valid array without the single element disruption, every pair starts at an even index, so nums[even] == nums[even + 1]. If this condition holds at the middle even index, the single element must be to the right. Otherwise, it is on the left or at the current position.
l = 0 and r = n - 1.l < r:m. If m is odd, decrement it to make it even.nums[m] != nums[m + 1], the single element is at or before m; set r = m.m; set l = m + 2.nums[l].We can use XOR with 1 to elegantly find the pair index. For even indices, m ^ 1 gives m + 1; for odd indices, it gives m - 1. This means nums[m] should equal nums[m ^ 1] if we are in the portion before the single element. If they differ, the single element is at or before index m.
l = 0 and r = n - 1.l < r:m.nums[m] != nums[m ^ 1], the single element is at or before m; set r = m.m; set l = m + 1.nums[l].Many candidates jump straight to the XOR solution without recognizing that the sorted property enables an binary search approach. While XOR works correctly, it only achieves time complexity and fails to leverage the key constraint that makes this problem unique.
The binary search solution relies on understanding that before the single element, pairs start at even indices (index 0, 2, 4...) and after it, this pattern shifts. A common mistake is getting the parity check backwards or not properly handling whether to compare with the left or right neighbor based on the current index.
When checking neighbors at m-1 or m+1, failing to validate bounds can cause array index out-of-bounds errors. This is especially problematic at the edges of the array where the single element might be the first or last element.