MediumBinary Search

Single Element in a Sorted Array โ€” Solution

Problem

You are given a sorted array of integers where every value appears exactly twice โ€” except for one value that appears exactly once. Find and return that unique element. Your solution must run in O(log n) time and use O(1) extra space.

  • Input: [1, 1, 2, 3, 3, 4, 4, 8, 8]
  • Output: 2
  • Explanation: Every element except 2 appears twice; 2 is the unique single element.

Counter-example: [3, 3, 7, 7, 10, 11, 11] โ€” the pairs stop aligning at even indices after position 4, revealing that 10 at index 4 is the single element.

Intuition

Because every value appears twice, the pairs in the sorted array start out aligned at even indices (index 0 and 1, then 2 and 3, and so on). The single element breaks this alignment: everything to its right is shifted by one, so pairs now straddle odd/even boundaries. Binary search can detect this shift at any midpoint without scanning the entire array.

Approach 1 โ€” XOR Scan

XOR every number together. Paired values cancel out (x ^ x = 0), leaving only the single element (x ^ 0 = x). No sorting structure is exploited, but the code is remarkably short.

  1. Initialize result = 0.
  2. XOR every element in the array into result.
  3. Return result.
1def singleNonDuplicate(nums: list[int]) -> int:
2    result = 0
3    for num in nums:
4        result ^= num  # paired values cancel; only the unique one survives
5    return result

Time: O(n) โ€” visits every element once.
Space: O(1) โ€” only a single integer accumulator.

Approach 2 โ€” Binary Search on Pair Alignment

Before the single element, nums[even_index] == nums[even_index + 1]. After it, the pairing is off โ€” nums[even_index] != nums[even_index + 1]. Snap the midpoint to an even index and check which side of the boundary we are on.

  1. Set lo = 0, hi = len(nums) - 1.
  2. While lo < hi: compute mid; if mid is odd, subtract 1 to make it even.
  3. If nums[mid] == nums[mid + 1], the pair at mid is intact โ€” single element is to the right, so lo = mid + 2.
  4. Otherwise, the pair is broken โ€” single element is at mid or to the left, so hi = mid.
  5. Return nums[lo].
1def singleNonDuplicate(nums: list[int]) -> int:
2    lo, hi = 0, len(nums) - 1
3    while lo < hi:
4        mid = (lo + hi) // 2
5        if mid % 2 == 1:
6            mid -= 1  # always evaluate at an even index so pair-check is meaningful
7        if nums[mid] == nums[mid + 1]:
8            lo = mid + 2  # pair is intact; single element lies further right
9        else:
10            hi = mid  # pair broken here; single element is at mid or to its left
11    return nums[lo]

Time: O(log n) โ€” halves the search space each iteration.
Space: O(1) โ€” only two pointers.

Complexity Summary

ApproachTimeSpaceWhen to use
XOR ScanO(n)O(1)When the O(log n) constraint is not required; simpler and zero risk of pointer bugs
Binary SearchO(log n)O(1)When the problem explicitly requires sub-linear time, or the array is very large

Common Mistakes

  • Checking the wrong neighbor after adjusting mid: After snapping mid down to even, always compare nums[mid] with nums[mid + 1] โ€” comparing with nums[mid - 1] instead gives wrong results because mid - 1 may be the other half of a pair from the left region.
  • Setting lo = mid + 1 instead of lo = mid + 2: When nums[mid] == nums[mid + 1], both indices belong to a complete pair that lies before the single element โ€” you must skip both, not just one.
  • Forgetting to snap mid to even: If mid is odd, nums[mid] is the second element of a pair. The pair-alignment rule (nums[even] == nums[even + 1] before the single element) only holds at even starting indices, so checking from an odd index gives a misleading result.
  • Accidentally going out of bounds: When mid is the last even index (e.g., mid == len - 1), nums[mid + 1] would be out of bounds. Anchoring hi to the last element and only snapping mid down (never up) keeps mid + 1 always valid while lo < hi.
  • Applying XOR when O(log n) is required: XOR is elegant but O(n). If the interviewer specifies logarithmic time โ€” as this problem does โ€” the XOR solution will not be accepted even though it produces the correct answer.

Related Problems

Ready to practice? Try it on SkillFlow

Adaptive problems, AI follow-up interviews, and a skill score that shows exactly where you need to improve.

Practice This Problem โ†’