Given an array arr[] of integers of size n, where each element is in the range 1 to n and each element can occur at most twice, find all elements that appear twice in the array.
Examples:Â
Input: arr[] = [2, 3, 1, 2, 3]
Output: [2, 3]
Explanation: 2 and 3 occur twice in the given array.Input: arr[] = [3, 1, 2]
Output: []
Explanation: There is no repeating element in the array, so the output is empty.
Table of Content
[Naive Approach] Nested Loops - O(n2) Time and O(1) Space
The Idea is to iterate through each element and do the following for it,
- If already exists in the result.
- If not, scan the rest of the array to see if it appears again. If it does, add it to the result.
#include <iostream>
#include <vector>
using namespace std;
vector<int> findDuplicates(vector<int>& arr) {
vector<int> ans;
// traverse each element in the array
for (int i = 0; i < arr.size(); i++) {
int cnt = 0;
// check if element is already added to result
for (auto &it : ans) {
if (arr[i] == it) {
cnt++;
break;
}
}
// if already added, skip checking again
if (cnt) continue;
// check if current element appears
// again in the rest of the array
for (int j = i + 1; j < arr.size(); j++) {
if (arr[i] == arr[j]){
cnt++;
break;
}
}
// if duplicate found, add to result
if (cnt) ans.push_back(arr[i]);
}
return ans;
}
int main() {
vector<int> arr = {2, 3, 1, 2, 3};
vector<int> res = findDuplicates(arr);
for (int ele : res) {
cout << ele << ' ';
}
cout << endl;
return 0;
}
import java.util.ArrayList;
class GfG {
public static ArrayList<Integer> findDuplicates(int[] arr) {
ArrayList<Integer> ans = new ArrayList<>();
// traverse each element in the array
for (int i = 0; i < arr.length; i++) {
int cnt = 0;
// check if element is already added to result
for (int it : ans) {
if (arr[i] == it) {
cnt++;
break;
}
}
// if already added, skip checking again
if (cnt > 0) continue;
// check if current element appears again
// in the rest of the array
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]){
cnt++;
break;
}
}
// if duplicate found, add to result
if (cnt > 0) ans.add(arr[i]);
}
return ans;
}
public static void main(String[] args) {
int[] arr = {2, 3, 1, 2, 3};
ArrayList<Integer> res = findDuplicates(arr);
for (int ele : res) {
System.out.print(ele + " ");
}
System.out.println();
}
}
def findDuplicates(arr):
ans = []
# traverse each element in the array
for i in range(len(arr)):
cnt = 0
# vheck if element is already added to result
for it in ans:
if arr[i] == it:
cnt += 1
break
# if already added, skip checking again
if cnt:
continue
# check if current element appears again
# in the rest of the array
for j in range(i + 1, len(arr)):
if arr[i] == arr[j]:
cnt += 1
break
# if duplicate found, add to result
if cnt:
ans.append(arr[i])
return ans
if __name__ == "__main__":
arr = [2, 3, 1, 2, 3]
res = findDuplicates(arr)
print(*res)
using System;
using System.Collections.Generic;
class GfG {
static List<int> findDuplicates(int[] arr) {
List<int> ans = new List<int>();
// traverse each element in the array
for (int i = 0; i < arr.Length; i++) {
int cnt = 0;
// check if element is already added to result
foreach (int it in ans) {
if (arr[i] == it) {
cnt++;
break;
}
}
// if already added, skip checking again
if (cnt > 0) continue;
// check if current element appears again
// in the rest of the array
for (int j = i + 1; j < arr.Length; j++) {
if (arr[i] == arr[j]){
cnt++;
break;
}
}
// if duplicate found, add to result
if (cnt > 0) ans.Add(arr[i]);
}
return ans;
}
public static void Main() {
int[] arr = { 2, 3, 1, 2, 3 };
List<int> res = findDuplicates(arr);
foreach (int ele in res) {
Console.Write(ele + " ");
}
Console.WriteLine();
}
}
function findDuplicates(arr) {
const ans = [];
// traverse each element in the array
for (let i = 0; i < arr.length; i++) {
let cnt = 0;
// check if element is already added to result
for (let it of ans) {
if (arr[i] === it) {
cnt++;
break;
}
}
// if already added, skip checking again
if (cnt > 0) continue;
// check if current element appears again
// in the rest of the array
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]){
cnt++;
break;
}
}
// if duplicate found, add to result
if (cnt > 0) ans.push(arr[i]);
}
return ans;
}
// Driver Code
const arr = [2, 3, 1, 2, 3];
const res = findDuplicates(arr);
console.log(res.join(" "));
Output
2 3
[Better Approach] Frequency Array - O(n) Time and O(n) Space
The main Idea is to traverse the array once and count the occurrences of each element using a frequency array.
Then, iterate through the array to collect elements whose frequency 2, indicating they are duplicates.
#include <iostream>
#include <vector>
using namespace std;
vector<int> findDuplicates(vector<int>& arr) {
int n = arr.size();
// frequency array of size n+1 (1-based indexing)
vector<int> freq(n + 1, 0);
vector<int> ans;
// Ccount frequencies using the array
for (int num : arr) {
freq[num]++;
}
// collect elements that appear exactly twice
for (int i = 1; i <= n; i++) {
if (freq[i] == 2) {
ans.push_back(i);
}
}
return ans;
}
int main() {
vector<int> arr = {2, 3, 1, 2, 3};
vector<int> res = findDuplicates(arr);
for (int ele : res) {
cout << ele << ' ';
}
cout << endl;
return 0;
}
import java.util.ArrayList;
class GfG {
static ArrayList<Integer> findDuplicates(int[] arr) {
int n = arr.length;
// frequency array (1-based indexing)
int[] freq = new int[n + 1];
ArrayList<Integer> ans = new ArrayList<>();
// count frequencies using array
for (int num : arr) {
freq[num]++;
}
// collect elements that appear exactly twice
for (int i = 1; i <= n; i++) {
if (freq[i] == 2) {
ans.add(i);
}
}
return ans;
}
public static void main(String[] args) {
int[] arr = {2, 3, 1, 2, 3};
ArrayList<Integer> res = findDuplicates(arr);
for (int ele : res) {
System.out.print(ele + " ");
}
System.out.println();
}
}
def findDuplicates(arr):
n = len(arr)
# frequency array with 1-based indexing
freq = [0] * (n + 1)
ans = []
# count frequencies using the array
for num in arr:
freq[num] += 1
# collect elements that appear exactly twice
for i in range(1, n + 1):
if freq[i] == 2:
ans.append(i)
return ans
if __name__ == "__main__":
arr = [2, 3, 1, 2, 3]
res = findDuplicates(arr)
for ele in res:
print(ele, end=' ')
print()
using System;
using System.Collections.Generic;
class GfG {
static List<int> findDuplicates(int[] arr) {
int n = arr.Length;
// frequency array (1-based indexing)
int[] freq = new int[n + 1];
List<int> ans = new List<int>();
// count frequencies using array
foreach (int num in arr) {
freq[num]++;
}
// collect elements that appear exactly twice
for (int i = 1; i <= n; i++) {
if (freq[i] == 2) {
ans.Add(i);
}
}
return ans;
}
public static void Main() {
int[] arr = { 2, 3, 1, 2, 3 };
List<int> res = findDuplicates(arr);
foreach (int ele in res) {
Console.Write(ele + " ");
}
Console.WriteLine();
}
}
function findDuplicates(arr) {
const n = arr.length;
// frequency array (1-based indexing)
const freq = new Array(n + 1).fill(0);
const ans = [];
// count frequencies
for (let num of arr) {
freq[num]++;
}
// collect elements that appear exactly twice
for (let i = 1; i <= n; i++) {
if (freq[i] === 2) {
ans.push(i);
}
}
return ans;
}
// Driver code
const arr = [2, 3, 1, 2, 3];
const res = findDuplicates(arr);
console.log(res.join(" "));
Output
3 2
[Expected Approach] Negative Marking approach - O(n) Time and O(1) Space
The main Idea is to iterate over the array and use the value of each element as an index (after subtracting 1).
- If the element at that index is positive, we negate it to mark the number as visited.
- If it's already negative, it means we've seen it before, so we add it to the result.
This avoids extra space and works in linear time.
Steps:
- Traverse the array once, using each value arr[i] to compute an index idx = abs(arr[i]) - 1.
- Check the value at arr[idx]:
=> If it is positive, mark it as visited by setting arr[idx] = -arr[idx].
=> If it is already negative, it means arr[i] has been seen before, so it's a duplicate. - Add such duplicate values to the result list.
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
vector<int> findDuplicates(vector<int>& arr) {
vector<int> ans;
for (int i = 0; i < arr.size(); i++) {
// convert value to index (1-based to 0-based)
int idx = abs(arr[i]) - 1;
// if already visited, it's a duplicate
if (arr[idx] > 0){
// mark as visited by negating
arr[idx] = -arr[idx];
}
else{
ans.push_back(abs(arr[i]));
}
}
return ans;
}
int main() {
vector<int> arr = {2, 3, 1, 2, 3};
vector<int> res = findDuplicates(arr);
for (int ele : res) {
cout << ele << ' ';
}
cout << endl;
return 0;
}
import java.util.ArrayList;
class GfG {
public static ArrayList<Integer> findDuplicates(int[] arr) {
// convert value to index (1-based to 0-based)
ArrayList<Integer> ans = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
int idx = Math.abs(arr[i]) - 1;
// if already visited, it's a duplicate
if (arr[idx] < 0) {
ans.add(Math.abs(arr[i]));
} else {
// mark as visited
arr[idx] = -arr[idx];
}
}
return ans;
}
public static void main(String[] args) {
int[] arr = {2, 3, 1, 2, 3};
ArrayList<Integer> res = findDuplicates(arr);
for (int ele : res) {
System.out.print(ele + " ");
}
System.out.println();
}
}
def findDuplicates(arr):
ans = []
for i in range(len(arr)):
# convert value to index (1-based to 0-based)
idx = abs(arr[i]) - 1
# if already visited, it's a duplicate
if arr[idx] < 0:
ans.append(abs(arr[i]))
else:
# mark as visited
arr[idx] = -arr[idx]
return ans
if __name__ == "__main__":
arr = [2, 3, 1, 2, 3]
res = findDuplicates(arr)
print(*res)
using System;
using System.Collections.Generic;
class GfG {
public static List<int> findDuplicates(int[] arr) {
List<int> ans = new List<int>();
for (int i = 0; i < arr.Length; i++) {
// convert value to index (1-based to 0-based)
int idx = Math.Abs(arr[i]) - 1;
// if already visited, it's a duplicate
if (arr[idx] < 0) {
ans.Add(Math.Abs(arr[i]));
} else {
// mark as visited
arr[idx] = -arr[idx];
}
}
return ans;
}
public static void Main() {
int[] arr = {2, 3, 1, 2, 3};
List<int> res = findDuplicates(arr);
foreach (int ele in res) {
Console.Write(ele + " ");
}
Console.WriteLine();
}
}
function findDuplicates(arr) {
const ans = [];
for (let i = 0; i < arr.length; i++) {
// convert value to index (1-based to 0-based)
let idx = Math.abs(arr[i]) - 1;
// if already visited, it's a duplicate
if (arr[idx] < 0) {
ans.push(Math.abs(arr[i]));
} else {
// mark as visited
arr[idx] = -arr[idx];
}
}
return ans;
}
// Driver Code
const arr = [2, 3, 1, 2, 3];
const res = findDuplicates(arr);
console.log(res.join(" "));
Output
2 3