Find All Duplicates in an Array
Use the array itself as the count array. Value v has the home nums[v − 1]. Swap every value home. A value that appears once ends up at its home. For a value that appears twice, one copy gets home and the other cannot — its home is taken by its twin. That stuck copy sits at some wrong index. So after placement, every i with nums[i] != i + 1 holds a duplicate.
Keep swapping nums[i] home while nums[i] != nums[nums[i] − 1]. After that, every index with nums[i] != i + 1 holds a duplicate value.
Problem
You are given an array nums of length n. Every value is between 1 and n, and every value appears once or twice.
Return every value that appears twice. The order of the answer does not matter.
Your algorithm must run in O(N) time and use only O(1) extra space (the output list does not count).
An integer array nums of length n, with 1 ≤ nums[i] ≤ n.
A list of all values that appear exactly twice, in any order.
2 and 3 each appear twice. Every other value appears once.
1 appears twice.
Nothing repeats, so the answer is empty.
- • n == nums.length
- • 1 ≤ n ≤ 10^5
- • 1 ≤ nums[i] ≤ n
- • Each value appears once or twice.
- • O(N) time and O(1) extra space (not counting the output).
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
The values are 1..n and the array has n slots. Is there a natural slot for each value?
- 2.
If I had unlimited memory, how would I notice that I am seeing a value for the second time?
- 3.
If two copies of the same value both want the same slot, what happens to the second one?
- 4.
When I move a value to its slot, where does the old resident go?
- 5.
When should I stop swapping at a position so the loop cannot run forever?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | For each i, look for an equal value at some j > i | O(N²) | O(1) |
| Better | Count each value in an array of size n + 1; report at count 2 | O(N) | O(N) |
| Optimal | Swap each value v home to index v − 1; values not at home are duplicates | O(N) | O(1) |
Why does this belong to this pattern?
- “values between 1 and n”Each value has a home index v − 1 inside the array.
- “appears once or twice”At most one extra copy per value — it will be the one left out of place.
- “O(1) extra space”No count array or hash set — the input must store "seen" itself.
- “return all duplicates”Read the answer off every misplaced slot, not just the first one.
This is the anchor of the duplicate sub-pattern. In the missing sub-pattern you read the index of a bad slot (i + 1 is missing). Here you read the value in the bad slot (nums[i] is a duplicate). It is the same placement loop; only what you collect afterwards changes. The stop condition must compare with the home's value, because the twin may already be sitting there.
Don't make this mistake
This is the pattern-confusion trap from plain cyclic sort, where every value is distinct. Here a value can repeat. On [1, 1], at i = 1 the value 1 is not at index 1, so the wrong loop swaps it with index 0 — which also holds 1. Nothing changes and the loop never ends. Check the home's value instead.
i + 1 is the value missing from the array (that is the Find All Numbers Disappeared question). The value sitting in the bad slot is the duplicate.
After one swap, the value that lands at i may also need to move. On [4, 3, 2, 7, 8, 2, 3, 1] a single swap per index ends with [7, 2, 3, 4, 1, 2, 3, 8] and reports [7, 1, 2, 3] instead of [2, 3].
Both find the duplicates, and the judge may accept them, but they break the stated limits. The values being 1..n is the signal that the array can be its own count array.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Cyclic Sort translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.