Find All Duplicates in an Array
Master this topic with zero to advance depth.
Find All Duplicates in an Array
Since all integers are in the range [1, n], we can use the array itself as a frequency map by negating values at indices corresponding to the numbers seen. If we encounter an already negative value, it's a duplicate.
Given an integer array nums of length n where all the integers of nums are in the range [1, n] and each integer appears once or twice, return an array of all the integers that appears twice. You must solve the problem without using extra space and in O(n) runtime.
Visual Representation
nums = [4, 3, 2, 7, 8, 2, 3, 1]
Index 0 (4): Mark index 3 -> [4, 3, 2, -7, 8, 2, 3, 1]
Index 1 (3): Mark index 2 -> [4, 3, -2, -7, 8, 2, 3, 1]
...
Index 5 (2): Index 1 is already negative (-3)! DUPLICATE FOUND: 2Examples
2 and 3 appear twice in the array.
1 appears twice.
Level I: Brute Force (Nested Loops)
Intuition
We check every element against all subsequent elements to find duplicates. If a match is found, we add it to our result list (handling duplicates in the result list if necessary).
Detailed Dry Run
| i | j | nums[i] | nums[j] | Match? | Result |
|---|---|---|---|---|---|
| 0 | 1 | 4 | 3 | No | [] |
| 2 | 5 | 2 | 2 | Yes | [2] |
| 1 | 6 | 3 | 3 | Yes | [2, 3] |
Level II: HashSet / Frequency Array
Intuition
Use an auxiliary Hash Set or boolean array to track which numbers have been seen so far. If a number is already in the set, it's a duplicate.
Detailed Dry Run
| Num | Seen? | Action | Result |
|---|---|---|---|
| 4 | No | Add to Set | [] |
| 3 | No | Add to Set | [] |
| 2 | No | Add to Set | [] |
| 2 | YES | Add to Result | [2] |
Level III: Optimal Solution (In-place Negation)
Intuition
Since all integers are in the range [1, n], we can use the array itself as a hash table. For each number x, we go to the index abs(x)-1. If the value at that index is already negative, we know we've seen x before, so x is a duplicate. Otherwise, we negate the value to 'mark' it as seen.
Detailed Dry Run
Marking Process
nums = [4, 3, 2, 7, 8, 2, 3, 1]
[4, 3, 2, 7, 8, 2, 3, 1] Iter 1: x=4, Mark index 3 (4-1)
^
[4, 3, 2, -7, 8, 2, 3, 1] Iter 5: x=2, index 1 (2-1) is 3 (>0), mark
^
[4, -3, 2, -7, 8, 2, 3, 1] Iter 6: x=2, index 1 is -3 (<0). FOUND DUPLICATE!| Num (x) | Index (|x|-1) | Value at Index | Action | Result | | :--- | :--- | :--- | :--- | :--- | | 4 | 3 | 7 | Mark: nums[3]=-7 | [] | | 3 | 2 | 2 | Mark: nums[2]=-2 | [] | | 2 | 1 | 3 | Mark: nums[1]=-3 | [] | | 7 | 6 | 3 | Mark: nums[6]=-3 | [] | | 2 | 1 | -3 | Already Negative! | [2] |
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.