Single Number


Problem Link
Problem Statement
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.
Examples:
Input: nums = [2,2,1]
Output: 1
Input: nums = [4,1,2,1,2]
Output: 4
Input: nums = [1]
Output: 1
Before Coding: Think Like a Human
Imagine someone hands you a list of numbers and asks :
"Are there any number here that has been mentioned only once?"
A human approach:
Create a count starting with 0.
Start from the first element and see if it appears more than once.
If yes, go to the second element and repeat the process.
Repeat the process if not
Return the element with count 1.
That human-first approach gives us multiple ways to solve this. But — plot twist — the question demands, "You must implement a solution with a linear runtime complexity and use only constant extra space."
So we need an approach that has linear runtime complexity which is Time Complexity of O(n)
and constant extra space. It means your solution must have a space complexity of O(1)
, not grow with the input size.
Let’s unpack a few strategies before we hit the best one.
1. Brute Force Approach
Pattern alert: This is the 4th time we’ve seen brute force creep in. We’ve all been there. When in doubt, compare everything with everything.
function singleNumber(nums) {
for (let i = 0; i < nums.length; i++) { // Step 1: Iterate over each number
let count = 0; // Step 2: set count for current number
for (let j = 0; j < nums.length; j++) { // Step 3: Check against every number
if (nums[i] === nums[j]) {
count++; // Step 4: Count how many times nums[i] appears
}
}
if (count === 1) { // Step 5: If it appears only once
return nums[i]; // Step 6: Return it
}
}
}
This technically works, but it’s like trying to find a book in a library by checking every single shelf... twice. Too slow for large input. Remember two nested loops, makes the time complexity O(n²) and the question constraint is asking for linear runtime complexity. As for the space complexity a few variables (like let count= 0
) is Constant space — doesn't grow with input, hence O(1)
2. Using Hash Set/Object
Let’s shift our mindset think like a problem solver, not just a coder. Instead of comparing every number to every other number (which is slow), let’s count how many times each number shows up. If something only shows up once, it’s our answer.
This is where a HashMap (a plain JavaScript object, in this case) becomes your best friend — it lets you store each number as a key, and its count as the value.
function singleNumber(nums) {
const countMap = {}; // Step 1: Initialize an empty object (our hashmap)
for (const num of nums) {
// Step 2: Loop through the array and count occurrences
countMap[num] = (countMap[num] || 0) + 1;
// - If the number is already in the map, increment its count
// - If not, `countMap[num]` is undefined, so we treat it as 0 and add 1
}
for (const num in countMap) { // Step 3: Loop through the hashmap
if (countMap[num] === 1) { // Step 4: Find the one with a count of exactly 1
return Number(num); // All keys in objects are strings, so we convert back to number
}
}
}
JavaScript object keys give us O(1) average lookup and insertion time — that means checking and updating a value is fast, regardless of how big the input is. Because we only loop through the array once to build the map and then loop through the map once to find the unique number.
Time Complexity: O(n)
Loop once to build the map: O(n)
Loop again through the map: O(n) (in the worst case, if all numbers are unique)
Space Complexity: O(n) , We store up to n numbers in our map, if all are unique ❌ But it violates the constant space rule.
Use this pattern whenever you:
Need to count how many times something appears
Are okay with using extra space for speed
Want readability and simplicity over clever tricks
What if I told you , you can do it without extra space but keeping the time complexity to O(n). let’s get into it
3. XOR Method (Best for Time & Space)
So here’s something cool — XOR might sound like a techy buzzword, but it’s actually short for "exclusive OR." It’s a logical operator that returns true
only when the two inputs are different. In simple terms:
1 ^ 1 = 0
(same? cancel out)1 ^ 0 = 1
(different? pass through)
This neat little trick turns out to be super efficient — it shines in problems where every number appears exactly twice, except one.Let’s dive into the nitty-gritty and break down how it works, so we can appreciate the elegance behind it.
But first, let’s visualize this.
Think of the XOR as a “magic canceler” — every time it sees a duplicate, it cancels it out. Let’s visualize it like you're holding a running total.
[4, 1, 2, 1, 2] //Your goal is to find the one number that doesn’t have a duplicate.
let result = 0; //We'll start with zero
for (let num of nums) {
result ^= num;
}
//1st Loop :
//result = 0 ^ 4 // 0 is your starting point & num = 4
//0 ^ 4 = 4
//Now result = 4 //“I’ve seen 4 for the first time, I’m holding onto it.”
//2nd Loop
//result = 4 ^ 1
//4 ^ 1 = 5
//Now result = 5 //“Now I’ve also seen 1, I XOR it with 4 and get 5 (just a temporary mix).”
//3rd Loop
//result = 5 ^ 2
//5 ^ 2 = 7
//Now result = 5 //“I mix in 2 — now the result is 7”
//4th Loop
//result = 7 ^ 1 //We’ve seen 1 before! Now it’s canceling out! in 2nd loop
//7 ^ 1 = 6
//Now result = 5 //“The 1 I just saw canceled out the earlier 1 — result changes.”
//5th Loop
//result = 6 ^ 2 //We’ve seen 2 before! Now it’s canceling out! in 3rd loop
//6 ^ 2 = 4
//Now result = 4 //“Final answer: 4 — the only number that never got canceled out.”
Think of it like below as well
Start empty (0)
Grab 4 → [4]
Touch 1 → [4,1]
Touch 2 → [4,1,2]
Touch 1 again → cancels previous 1 → [4,2]
Touch 2 again → cancels previous 2 → [4]
Final in hand: [4] ✅
You don’t need to remember everything, just carry one value (
result
) and keep XORing as you go.Every duplicate cancels out and the unique number survives.
Let’s bring it home with the full function:
function singleNumber(nums) {
let result = 0
for(let num of nums){
result ^= num
}
return result
}
Time Complexity O(n)
— linear time
Space ComplexityO(1)
Final Thoughts
Finding the one non-duplicate number might seem routine. But this problem, like many good LeetCode problems, teaches us patterns.
The Big Lesson?
Sometimes, the best solution isn’t the most obvious — it’s the one that cancels all the noise and leaves the truth behind.
Keep stacking these mental models.
Because every time you solve a problem like this, you're not just writing code.
You're training your brain to see through the chaos, one XOR at a time.
Subscribe to my newsletter
Read articles from Adiam Ahmed directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
