Finding a unique element in an array is a classic interview problem that tests your understanding of bit manipulation and space optimization. This problem frequently appears in technical interviews at companies like Google, Amazon, and Microsoft, where interviewers assess whether you can recognize when bitwise operations eliminate the need for additional memory.
Problem statement
Given an array of integers where every element appears exactly twice except for one element that appears only once, find and return that single element. Your solution must run in linear time complexity and use only constant extra space.
Constraints:
- 1 ≤
nums.length≤ 3 × 10⁴ - -3 × 10⁴ ≤
nums[i]≤ 3 × 10⁴ - Each element in the array appears twice except for exactly one element which appears only once.
Examples
| Input | Output | Explanation |
[4, 5, 6, 5, 6] | 4 | The numbers 5 and 6 each appear twice, while 4 appears only once. |
[7] | 7 | The array contains only one element, so that element is the answer. |
[5, 9, 5, 3, 9] | 3 | Both 5 and 9 appear twice, leaving 3 as the unique element. |
Why counting duplicates is inefficient
A straightforward idea is to check each number and count how many times it appears in the array. That means for every element, we scan the entire array to see if it has a pair or not.
This does work logically, but it repeats the same counting work again and again, which becomes expensive as the array grows.
The naive counting approach does repeated scans over the same elements, so the time complexity is o(n^2) in the worst case, with o(1) extra space. With nums.length up to 3 * 10^4, o(n^2) can be roughly 9 * 10^8 comparisons, which is not realistic for interview constraints.
A hash map frequency count improves time to o(n), but it uses o(n) extra space, which violates the constant-space requirement.
Optimized approach using bit manipulation
To meet both constraints, we need a method where duplicates eliminate each other without storing counts.
XOR does exactly that:
a ^ a = 0a ^ 0 = a- XOR is associative and commutative, so order does not matter.
So if we XOR all numbers together, every pair cancels to 0, and the only thing left is the number that does not have a matching duplicate.
This still works with negatives because XOR operates on the binary representation of integers. In Python, integers have arbitrary precision, but XOR is still consistent and cancellation still holds because the same value XORed with itself always becomes 0.
Common approaches fail here because sorting takes o(n log n) time and a set or dictionary takes o(n) extra space. XOR keeps a single running accumulator, so we stay at o(1) space.
Step-by-step algorithm
- Initialize a variable
resultto 0. This will serve as our accumulator for the XOR operations. - Iterate through each element
numin the input arraynums. For each elementnum:- Compute
result = result ^ num(XOR the current element with the accumulated result).
- Compute
- After processing all elements, the
resultvariable will contain the single number that appears only once. - Return the
resultas the final answer.
Code implementation
Time complexity
The time complexity of this algorithm is O(n), where n represents the number of elements in the input array. We traverse the array exactly once, performing a constant-time XOR operation for each element. Since XOR is a bitwise operation that executes in O(1) time regardless of the magnitude of the numbers involved, the total time is directly proportional to the array size. There are no nested loops, recursion, or additional passes through the data, making this a truly linear solution.
Space complexity
The space complexity is O(1), meaning we use constant extra space. Regardless of the input size, we only maintain a single integer variable result to store the running XOR value. We don’t allocate any data structures that grow with the input size, such as hash maps, sets, or additional arrays. The space used remains constant whether the input array contains 10 elements or 10,000 elements, which satisfies the problem’s strict space constraint.
Common pitfalls and interview tips
- Forgetting the XOR identity properties: Many candidates know about XOR but forget that x ⊕ x = 0 and x ⊕ 0 = x. These properties are the foundation of this solution. During an interview, explicitly state these properties when explaining your approach to demonstrate deep understanding of bitwise operations.
- Attempting to use sum-based approaches without considering edge cases: Some candidates try to calculate
2 × (sum of unique elements) - (sum of all elements). While this mathematically works, it’s prone to integer overflow with large numbers and becomes complicated with negative values. The XOR approach avoids these pitfalls entirely and is more elegant. - Not considering the commutative nature of XOR: A common mistake is thinking that the order of elements matters or that we need to pair elements before XORing. Remember that XOR is both commutative and associative, so
a ^ b ^ cequalsc ^ a ^ bequalsb ^ c ^ a. This property allows us to process elements in any order without sorting.