Find All Duplicates in an Array
MediumUpdated: Jul 29, 2025
Practice on:
Problem
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 write an algorithm that runs in O(n) time and uses only constant extra space.
Examples
Example 1:
Input:
nums = [4,3,2,7,8,2,3,1]
Output:
[2,3]
Example 2:
Input:
nums = [1,1,2]
Output:
[1]
Example 3:
Input:
nums = [1]
Output:
[]
Solution
Method 1 – Cyclic Sort for In-Place Duplicate Detection
Intuition
Since all numbers are in the range [1, n], we can use the array indices to place each number at its correct position (i.e., value v at index v-1). If a number is already at its correct position or a duplicate is found, we skip it. This way, duplicates will be left at positions where the value does not match the index + 1.
Approach
- Iterate through the array and for each index i, while nums[i] != nums[nums[i] - 1], swap nums[i] with nums[nums[i] - 1].
- After the swaps, iterate through the array again. If nums[i] != i + 1, then nums[i] is a duplicate.
- Collect all such duplicates in a result list and return it.
Complexity
- ⏰ Time complexity:
O(n), as each element is swapped at most once. - 🧺 Space complexity:
O(1), since the algorithm works in-place and uses only a result list for output.
Code
C++
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n; ++i) {
while (nums[i] != nums[nums[i] - 1]) {
swap(nums[i], nums[nums[i] - 1]);
}
}
vector<int> ans;
for (int i = 0; i < n; ++i) {
if (nums[i] != i + 1) ans.push_back(nums[i]);
}
return ans;
}
};
Go
func findDuplicates(nums []int) []int {
n := len(nums)
for i := 0; i < n; i++ {
for nums[i] != nums[nums[i]-1] {
nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]
}
}
ans := []int{}
for i := 0; i < n; i++ {
if nums[i] != i+1 {
ans = append(ans, nums[i])
}
}
return ans
}
Java
class Solution {
public List<Integer> findDuplicates(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
while (nums[i] != nums[nums[i] - 1]) {
int tmp = nums[i];
nums[i] = nums[tmp - 1];
nums[tmp - 1] = tmp;
}
}
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (nums[i] != i + 1) ans.add(nums[i]);
}
return ans;
}
}
Python
class Solution:
def findDuplicates(self, nums: list[int]) -> list[int]:
n = len(nums)
for i in range(n):
while nums[i] != nums[nums[i] - 1]:
nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
return [v for i, v in enumerate(nums) if v != i + 1]
Kotlin
class Solution {
fun findDuplicates(nums: IntArray): List<Int> {
val n = nums.size
for (i in 0 until n) {
while (nums[i] != nums[nums[i] - 1]) {
val tmp = nums[i]
nums[i] = nums[tmp - 1]
nums[tmp - 1] = tmp
}
}
val ans = mutableListOf<Int>()
for (i in 0 until n) {
if (nums[i] != i + 1) ans.add(nums[i])
}
return ans
}
}
TypeScript
function findDuplicates(nums: number[]): number[] {
const n = nums.length;
for (let i = 0; i < n; i++) {
while (nums[i] !== nums[nums[i] - 1]) {
const tmp = nums[i];
nums[i] = nums[tmp - 1];
nums[tmp - 1] = tmp;
}
}
const ans: number[] = [];
for (let i = 0; i < n; i++) {
if (nums[i] !== i + 1) ans.push(nums[i]);
}
return ans;
}
Rust
impl Solution {
pub fn find_duplicates(nums: &mut Vec<i32>) -> Vec<i32> {
let n = nums.len();
for i in 0..n {
while nums[i] != nums[(nums[i] - 1) as usize] {
let j = (nums[i] - 1) as usize;
nums.swap(i, j);
}
}
let mut ans = Vec::new();
for (i, &v) in nums.iter().enumerate() {
if v != (i as i32) + 1 {
ans.push(v);
}
}
ans
}
}