Given a non-empty array of integers nums, every element appears twice except for one. Find that single one.
You must implement a solution with a linear runtime complexity and use only constant extra space.
1 <= nums.length <= 3 * 104-3 * 104 <= nums[i] <= 3 * 104We have a nested loop: for each of the elements, we scan up to others, giving total comparisons.
Only a constant number of variables (found, i, j) are used regardless of input size.
This brute-force approach checks each element to see whether any other element in the array shares its value. For each index i, we scan all other indices j; if no match is found, that element has no duplicate and must be the single number. While correct, this requires comparing every element against every other, which is inefficient for large inputs.
Building the set and computing both sums each require a single pass over the input, so the overall time is .
The set stores up to unique elements, which is in the worst case.
This approach exploits a mathematical identity: if every number appeared exactly twice, the sum of the array would equal twice the sum of its unique values. Since one number appears only once, computing 2 * sum(unique_values) - sum(all_values) cancels out all pairs and isolates the single number. We build a set to deduplicate, then compute both sums in a single linear pass each.
We make a single pass through the array, and each set add/remove/has operation is on average, giving total.
The set holds at most elements simultaneously, so space is .
This approach uses a set as a toggle: the first time we encounter a number we add it to seen, and the second time we remove it. Since every number except one appears exactly twice, paired numbers are added and then removed, leaving only the single number in the set at the end.
The sort dominates the runtime at ; the subsequent linear scan is and does not change the overall complexity.
Sorting is done in-place with no auxiliary data structures needed.
By sorting the array, all duplicate pairs become adjacent. We then step through the sorted array two elements at a time; if a pair doesn't match, the current element is the single number. If no mismatch is found during the loop, the single number must be the last element, which had no pair to sit beside.
We make a single pass through the array performing one XOR operation per element, so the time complexity is .
Only a single result variable is needed regardless of input size.
This approach leverages two key XOR properties: any number XORed with itself equals 0, and any number XORed with 0 equals itself. By XORing all elements together, every number that appears twice cancels out to 0, and only the single unpaired number remains as the final result.
| Approach | Rating | Time Complexity | Space Complexity | Advantages | Disadvantages |
|---|---|---|---|---|---|
| Brute Force | No extra space needed | Quadratic time makes it impractical for large inputs | |||
| Math | Intuitive mathematical identity | Requires extra space for the set | |||
| Toggle Set | Clean, readable toggle logic | Requires extra space for the set | |||
| Sorting | Constant space with no extra data structures | Superlinear time due to sorting | |||
| XOR Bit Manipulation | Optimal time and space; elegantly leverages XOR properties | Requires familiarity with bitwise operations |
The optimal approach for this problem is Solution 5: XOR Bit Manipulation, which achieves time complexity and space complexity. By XORing all elements together, every paired duplicate cancels out to zero, leaving only the single unpaired number with no extra memory required.
class Solution: def singleNumber(self, nums: List[int]) -> int: # Iterate through each number in the list and check if it appears more than once. for i in range(len(nums)): found = False # Flag to indicate if a duplicate is found
# Check if the current number appears more than once in the list. for j in range(len(nums)): if i != j and nums[i] == nums[j]: found = True break
if not found: # If no duplicate is found, return the current number as the single number. return nums[i]class Solution: def singleNumber(self, nums: List[int]) -> int: set_nums = set(nums)
# Calculate the sum of the unique numbers and the sum of all numbers. sum_set = sum(set_nums) sum_nums = sum(nums)
# The single number is the difference between twice the sum of the unique numbers and the sum of all numbers. return 2 * sum_set - sum_numsclass Solution: def singleNumber(self, nums: List[int]) -> int: # Using a set to track seen numbers. If a number is seen again, it is removed from the set. seen = set()
for num in nums: if num in seen: # If the number is already in the set, it means we've seen it before, so we remove it. seen.remove(num) else: # If the number is not in the set, we add it to the set. seen.add(num)
# The single number will be the only element left in the set. return seen.pop()class Solution: def singleNumber(self, nums: List[int]) -> int: # Sort the array to bring duplicates together nums.sort()
# Iterate through the sorted array and check for pairs for i in range(0, len(nums) - 1, 2): if nums[i] != nums[i + 1]: return nums[i]
# If the single number is the last element in the sorted array return nums[-1]class Solution: def singleNumber(self, nums: List[int]) -> int: # XOR of a number with itself is 0, and XOR of a number with 0 is the number itself. result = 0
for num in nums: result ^= num
return result