Skip to content

Commit 7442a3c

Browse files
authored
Merge pull request #84 from SenthilkumarKailash/feature/137-Single-Number-II
Solution #137 - Kailash Senthilkumar - 09/08/2025
2 parents c2ae896 + 765cf6b commit 7442a3c

File tree

8 files changed

+352
-0
lines changed

8 files changed

+352
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Single Number II
2+
3+
**Difficulty:** Medium
4+
**Category:** Arrays, Bit Manipulation
5+
**Leetcode Link:** [Problem Link](https://leetcode.com/problems/single-number-ii/)
6+
7+
---
8+
9+
## 📝 Introduction
10+
11+
We are given an integer array `nums` where every element appears exactly **three times**, except for one element which appears exactly **once**. The task is to find and return this unique element.
12+
The solution must have:
13+
- **Linear runtime complexity** O(n)
14+
- **Constant extra space** O(1)
15+
16+
---
17+
18+
## 💡 Approach & Key Insights
19+
20+
The naive approach would involve counting the occurrences of each number (using a hash map), but that would require **O(n)** extra space, violating the space constraint.
21+
22+
Instead, we can use **bitwise manipulation** to track the count of each bit across all numbers:
23+
- Maintain two bitmasks:
24+
- **`ones`** → bits that have appeared exactly once so far.
25+
- **`twos`** → bits that have appeared exactly twice so far.
26+
- When a bit appears a **third time**, it is removed from both `ones` and `twos`.
27+
28+
The key insight:
29+
- `ones = (ones ^ num) & ~twos`
30+
- `twos = (twos ^ num) & ~ones`
31+
- XOR toggles the bit, AND with `~` masks out unwanted bits.
32+
33+
---
34+
35+
## 🛠️ Breakdown of Approaches
36+
37+
### 1️⃣ Brute Force / Naive Approach
38+
39+
- **Explanation:**
40+
Use a hash map to count each number’s frequency, then return the number with count = 1.
41+
- **Time Complexity:** O(n)
42+
- **Space Complexity:** O(n)
43+
44+
Example:
45+
`nums = [2, 2, 3, 2]` → Frequency: `{2: 3, 3: 1}` → Output: `3`
46+
47+
---
48+
49+
### 2️⃣ Bitwise Counting Approach
50+
51+
- **Explanation:**
52+
For each bit position (0–31), count how many numbers have that bit set.
53+
Take `count % 3` to determine if that bit belongs to the unique number.
54+
- **Time Complexity:** O(32n) ≈ O(n)
55+
- **Space Complexity:** O(1)
56+
57+
Example:
58+
Count bits column-wise → reconstruct the number.
59+
60+
---
61+
62+
### 3️⃣ Best / Final Optimized Approach (Bitmask Method)
63+
64+
- **Explanation:**
65+
Use `ones` and `twos` to track the counts of bits modulo 3.
66+
- **Time Complexity:** O(n) — single pass
67+
- **Space Complexity:** O(1) — only two variables used
68+
69+
Example/Dry Run for `nums = [2, 2, 3, 2]`:
70+
Binary:
71+
- 2 → `10`
72+
- 3 → `11`
73+
74+
Step-by-step:
75+
```
76+
Initial: ones=00, twos=00
77+
78+
num=2: ones=(00^10)&~00=10, twos=(00^10)&~10=00
79+
num=2: ones=(10^10)&~00=00, twos=(00^10)&~00=10
80+
num=3: ones=(00^11)&~10=01, twos=(10^11)&~01=00
81+
num=2: ones=(01^10)&~00=11, twos=(00^10)&~11=00
82+
Final: ones=11 (decimal 3)
83+
```
84+
Output: `3`
85+
86+
---
87+
88+
## 📊 Complexity Analysis
89+
90+
| Approach | Time Complexity | Space Complexity |
91+
| ------------- | --------------- | ---------------- |
92+
| Brute Force | O(n) | O(n) |
93+
| Bit Count | O(n) | O(1) |
94+
| Bitmask Method| O(n) | O(1) |
95+
96+
---
97+
98+
## 📉 Optimization Ideas
99+
100+
The **bitmask method** is already optimal for both runtime and space. Any further improvements would be micro-optimizations or hardware-specific.
101+
102+
---
103+
104+
## 📌 Example Walkthroughs & Dry Runs
105+
106+
Example:
107+
```
108+
Input: nums = [0, 1, 0, 1, 0, 1, 99]
109+
Output: 99
110+
111+
Step-by-step bitmask evolution:
112+
ones=0, twos=0
113+
Process each number using:
114+
ones = (ones ^ num) & ~twos
115+
twos = (twos ^ num) & ~ones
116+
Final ones=99 → Output
117+
```
118+
119+
---
120+
121+
## 🔗 Additional Resources
122+
123+
- [LeetCode Bit Manipulation Patterns](https://leetcode.com/tag/bit-manipulation/)
124+
- [GeeksforGeeks - Bitwise Operators](https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/)
125+
126+
---
127+
128+
Author: Kailash Senthilkumar
129+
Date: 09/08/2025
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution {
2+
public:
3+
int singleNumber(vector<int>& nums) {
4+
int ones = 0, twos = 0;
5+
for (int num : nums) {
6+
// Update 'ones' with bits appearing first time or third time
7+
ones = (ones ^ num) & ~twos;
8+
// Update 'twos' with bits appearing second time
9+
twos = (twos ^ num) & ~ones;
10+
}
11+
// 'ones' will contain the number that appears only once
12+
return ones;
13+
}
14+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution {
2+
public int singleNumber(int[] nums) {
3+
int ones = 0;
4+
int twos = 0;
5+
for(int num:nums){
6+
// This updates 'ones' with bits appearing first time or third time
7+
ones = (ones^num) & ~twos;
8+
// This updates 'twos' with bits appearing second time
9+
twos =(twos^num) & ~ones;
10+
11+
12+
13+
}
14+
// The 'ones' variable will contain the number that has appeared only once.
15+
return ones;
16+
}
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Solution:
2+
def singleNumber(self, nums):
3+
ones, twos = 0, 0
4+
for num in nums:
5+
# Update 'ones' with bits appearing first time or third time
6+
ones = (ones ^ num) & ~twos
7+
# Update 'twos' with bits appearing second time
8+
twos = (twos ^ num) & ~ones
9+
# 'ones' will contain the number that appears only once
10+
return ones
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Missing Number
2+
3+
**Difficulty:** Easy
4+
**Category:** Arrays, Bit Manipulation
5+
**Leetcode Link:** [Problem Link](https://leetcode.com/problems/missing-number/)
6+
7+
---
8+
9+
## 📝 Introduction
10+
11+
Given an array `nums` containing `n` distinct numbers in the range `[0, n]`, the task is to find the single number missing from this range. The input guarantees exactly one missing number.
12+
13+
**Constraints:**
14+
- `n` numbers, each unique, ranging from 0 to n.
15+
- Exactly one number in this range is missing.
16+
- Expected output: the missing number.
17+
18+
---
19+
20+
## 💡 Approach & Key Insights
21+
22+
The main idea is to leverage the **XOR property**:
23+
- XOR of a number with itself is 0 (`x ^ x = 0`).
24+
- XOR of a number with 0 is the number itself (`x ^ 0 = x`).
25+
- XOR is commutative and associative.
26+
27+
If we XOR all indices (0 to n) with all numbers in the array, the duplicates cancel out, leaving only the missing number.
28+
29+
---
30+
31+
## 🛠️ Breakdown of Approaches
32+
33+
### 1️⃣ Brute Force / Naive Approach
34+
35+
- **Explanation:**
36+
Loop through numbers from `0` to `n` and check if each is present in the array. Return the number that is not found.
37+
- **Time Complexity:** O(n²) — because for each number we scan the array.
38+
- **Space Complexity:** O(1) — no extra space needed apart from variables.
39+
40+
Example:
41+
Input: `[3, 0, 1]`
42+
Step 1: Check `0` → Found
43+
Step 2: Check `1` → Found
44+
Step 3: Check `2` → Missing → Output: `2`
45+
46+
---
47+
48+
### 2️⃣ Optimized Approach (Sum Formula)
49+
50+
- **Explanation:**
51+
Use the sum formula for the first `n` integers:
52+
`expectedSum = n * (n + 1) / 2`
53+
Subtract the actual sum of the array from `expectedSum` to get the missing number.
54+
- **Time Complexity:** O(n) — single pass to get the sum.
55+
- **Space Complexity:** O(1) — only variables for sums.
56+
57+
Example:
58+
Input: `[3, 0, 1]`
59+
n = 3 → Expected Sum = `6`
60+
Actual Sum = `4`
61+
Missing = `6 - 4 = 2`
62+
63+
---
64+
65+
### 3️⃣ Best / Final Optimized Approach (XOR Method)
66+
67+
- **Explanation:**
68+
XOR all numbers from `0` to `n` with all elements of the array. All pairs cancel out except the missing number.
69+
This avoids integer overflow (unlike sum approach for very large n) and still runs in O(n).
70+
- **Time Complexity:** O(n) — single pass.
71+
- **Space Complexity:** O(1) — no extra space.
72+
73+
Example:
74+
Input: `[3, 0, 1]`
75+
```
76+
xor = 0
77+
xor ^ 0 ^ 3 = 3
78+
xor ^ 1 ^ 0 = 4 (in binary cancels out)
79+
xor ^ 2 = 2 (final answer)
80+
```
81+
82+
---
83+
84+
## 📊 Complexity Analysis
85+
86+
| Approach | Time Complexity | Space Complexity |
87+
| ------------- | --------------- | ---------------- |
88+
| Brute Force | O(n²) | O(1) |
89+
| Optimized | O(n) | O(1) |
90+
| Best Approach | O(n) | O(1) |
91+
92+
---
93+
94+
## 📉 Optimization Ideas
95+
96+
The XOR method is already optimal for both time and space. Any further optimization would focus on language-specific performance tricks, but asymptotic complexity cannot be improved.
97+
98+
---
99+
100+
## 📌 Example Walkthroughs & Dry Runs
101+
102+
Example:
103+
Input: `nums = [3, 0, 1]`
104+
n = 3
105+
```
106+
xor = 0
107+
i = 0 → xor = 0 ^ 0 ^ 3 = 3
108+
i = 1 → xor = 3 ^ 1 ^ 0 = 2
109+
i = 2 → xor = 2 ^ 2 ^ 1 = 1
110+
Final: xor = 1 ^ 3 = 2
111+
Output: 2
112+
```
113+
114+
---
115+
116+
## 🔗 Additional Resources
117+
118+
- [LeetCode Discussion on XOR Trick](https://leetcode.com/problems/missing-number/discuss)
119+
- [Bit Manipulation Basics](https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/)
120+
121+
---
122+
123+
Author: Kailash Senthilkumar
124+
Date: 09/08/2025
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public:
3+
int missingNumber(vector<int>& nums) {
4+
int n = nums.size();
5+
6+
// Initialize xor to 0. This will hold the result of XOR operations.
7+
int xorResult = 0;
8+
9+
// Iterate through the array
10+
for (int i = 0; i < n; i++) {
11+
// XOR current index and the current number
12+
xorResult = xorResult ^ i ^ nums[i];
13+
}
14+
15+
// XOR with the last number n (because indices go from 0 to n-1, but range is 0 to n)
16+
xorResult = xorResult ^ n;
17+
18+
// The result is the missing number
19+
return xorResult;
20+
}
21+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution {
2+
public int missingNumber(int[] nums) {
3+
int n = nums.length;
4+
5+
// Initialize xor to 0. This will hold the result of XOR operations.
6+
int xor = 0;
7+
8+
// Iterate through the array
9+
for (int i = 0; i < n; i++) {
10+
// XOR current index and the current number
11+
xor = xor ^ i ^ nums[i];
12+
}
13+
14+
// XOR with the last number n (because indices go from 0 to n-1, but range is 0 to n)
15+
xor = xor ^ n;
16+
17+
// The result is the missing number
18+
return xor;
19+
}
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution:
2+
def missingNumber(self, nums):
3+
n = len(nums)
4+
5+
# Initialize xor to 0. This will hold the result of XOR operations.
6+
xor = 0
7+
8+
# Iterate through the array
9+
for i in range(n):
10+
# XOR current index and the current number
11+
xor = xor ^ i ^ nums[i]
12+
13+
# XOR with the last number n (because indices go from 0 to n-1, but range is 0 to n)
14+
xor = xor ^ n
15+
16+
# The result is the missing number
17+
return xor

0 commit comments

Comments
 (0)