Loading problems...
TL;DR: The optimal solution uses bitwise logic to simulate a ternary (base-3) counter that tracks the frequency of bits across all numbers, effectively cancelling out bits that appear three times.
The problem asks us to identify a unique integer from an array nums where every element appears exactly three times, except for one element which appears exactly once. This is a variation of the classic "Single Number" problem, but the triple occurrence constraint breaks the standard XOR solution. We must solve this "Single Number II" problem (LeetCode 137) with linear time complexity and constant space .
The most intuitive way to solve this is to count the frequency of every number in the array. We can use a hash map (dictionary) to store the counts.
Pseudo-code:
textcreate a hash map named counts for each number in nums: increment counts[number] for each number in counts: if counts[number] == 1: return number
Why it fails: While this approach is correct and runs in linear time , it requires space to store the hash map. The problem explicitly restricts us to constant extra space . Therefore, for large inputs (up to elements), the memory usage is suboptimal relative to the constraints, making this approach invalid for the specific requirements of the interview question.
The core insight is to treat the integers as vectors of 32 bits and process each bit position independently.
In the standard "Single Number" problem (where duplicates appear twice), we use XOR because XOR acts as addition modulo 2 without carry (). Here, duplicates appear three times. We need an operation that acts as addition modulo 3.
If we sum the bits at the -th position for all numbers:
0 at bit , the sum will be (since all other numbers appear in triplets).1 at bit , the sum will be .Therefore, if we sum the bits at every position and take the result modulo 3, the remainder is exactly the bit of the single number.
Visual Description:
Imagine a digital logic circuit or a state machine processing the stream of numbers. For any specific bit position (e.g., the 0-th bit), we start at state 00. When we encounter a 1, the state transitions to 01 (seen once). Another 1 moves it to 10 (seen twice). A third 1 resets it back to 00 (seen three times). This cycle repeats, effectively filtering out all numbers appearing three times, leaving only the bits of the unique number in the 01 state.

Let's trace the algorithm with nums = [2, 2, 3, 2].
Binary representations: 2 is 0010, 3 is 0011.
Initialization:
ones = 0000
twos = 0000
Step 1: Process 2 (0010)
ones: (0000 ^ 0010) & ~0000 = 0010 (Bit 1 seen once)twos: (0000 ^ 0010) & ~0010 = 0000 (Bit 1 not seen twice yet)ones=0010, twos=0000Step 2: Process 2 (0010)
ones: (0010 ^ 0010) & ~0000 = 0000 (Bit 1 cleared from ones)twos: (0000 ^ 0010) & ~0000 = 0010 (Bit 1 moved to twos)ones=0000, twos=0010Step 3: Process 3 (0011)
ones: (0000 ^ 0011) & ~0010 = 0011 & 1101 = 0001
3 enters ones.3 tries to enter ones, but twos has bit 1 set, so it is blocked.twos: (0010 ^ 0011) & ~0001 = 0001 & 1110 = 0000
ones (new) captures bits appearing 1st time or 4th time.twos (new) captures bits appearing 2nd time or 5th time.new_ones = (0000 ^ 0011) & ~0010 -> 0011 & 1101 -> 0001. (Bit 0 is now seen once).new_twos = (0010 ^ 0011) & ~0001 -> 0001 & 1110 -> 0000. (This transition logic is slightly complex to trace manually without the full truth table, but effectively Bit 1 was in twos, incoming is 1, so it should reset to 0. Bit 0 was 0, incoming is 1, goes to ones).twos. The formula uses the updated ones.ones became 0001.twos = (0010 ^ 0011) & ~0001 = 0001 & 1110 = .ones=0001, twos=0000Step 4: Process 2 (0010)
ones: (0001 ^ 0010) & ~0000 = 0011twos: (0000 ^ 0010) & ~0011 = 0000ones=0011 (Wait, this trace is slightly off because the example numbers are interleaved. The single number is 3 (0011). The 2s should cancel out).Let's re-verify the logic of the single number 3 (0011).
The 2s appear 3 times. Their bits at position 1 will cycle . They vanish.
The 3 appears 1 time. Its bits at position 0 and 1 will enter state 1.
Result ones should be 3.
Final result is returned from ones.
The algorithm implements a modulo-3 counter for each bit position .
Let be the sum of the -th bits of all numbers in the array.
We can write , where is the -th bit of the single number (0 or 1), and is the number of groups of three.
Our variables ones and twos maintain the state of this count:
ones is 1 and twos is 0.ones is 0 and is 1.Since the unique element appears exactly once, the final count for its active bits will be . Thus, the variable ones will hold the exact bitmask of the single number.
cppclass Solution { public: int singleNumber(vector<int>& nums) { int ones = 0; int twos = 0; for (int num : nums) { // Update 'ones' with the new number, but remove bits that are now in 'twos' ones = (ones ^ num) & ~twos; // Update 'twos' with the new number, but remove bits that are now in 'ones' twos = (twos ^ num) & ~ones; } return ones; } };
javaclass Solution { public int singleNumber(int[] nums) { int ones = 0; int twos = 0; for (int num : nums) { // 'ones' captures bits that have appeared 1st time or 4th time, etc. // If a bit is already in 'twos', it means it has appeared twice. // Adding it again (3rd time) should clear it from both. ones = (ones ^ num) & ~twos; // 'twos' captures bits that have appeared 2nd time or 5th time, etc. // We use the updated 'ones' to ensure a bit isn't in both states. twos = (twos ^ num) & ~ones; } return ones; } }
pythonclass Solution: def singleNumber(self, nums: List[int]) -> int: ones = 0 twos = 0 for num in nums: # Update 'ones' to track bits seen once # If bit is in 'twos', it means it was seen twice before, so now 3 times -> clear it ones = (ones ^ num) & ~twos # Update 'twos' to track bits seen twice # If bit is in 'ones' (updated), it means it is seen once now, so not twice twos = (twos ^ num) & ~ones return ones
nums exactly once. Inside the loop, we perform a constant number of bitwise operations (XOR, AND, NOT). This is strictly linear time.ones and twos) regardless of the input size. This satisfies the constant space constraint.The Bit Manipulation pattern used here is versatile. Understanding how to manage state with XOR and masks applies to:
The "modulo state machine" logic can be generalized to find a number appearing once where others appear times, provided you construct the appropriate state transitions.
result ^= num like in Single Number I.x ^ x = 0 works for pairs. For triplets, x ^ x ^ x = x. This leaves the XOR sum of all unique numbers, not just the single one. This approach cannot distinguish between the single number and the numbers appearing three times.nums[i] == nums[i+1].0000twos). Now we see it a 3rd time (in 3). It should reset to 0. Correct.ones. Correct.twosones/twos bitwise solution is considered the "optimal" or "canonical" solution for this pattern because it avoids the nested loop and is more computationally efficient on hardware.