Find duplicates in O(n) time and O(n) extra space | Set 1
Last Updated :
14 Oct, 2024
Given an array of n elements that contains elements from 0 to n-1, with any of these numbers appearing any number of times. Find these repeating numbers in O(n) and use only constant memory space.
Note: The repeating element should be printed only once.
Example:
Input: n=7 , array[]={1, 2, 3, 6, 3, 6, 1}
Output: 1, 3, 6
Explanation: The numbers 1 , 3 and 6 appears more than once in the array.
Input : n = 5 and array[] = {1, 2, 3, 4 ,3}
Output: 3
Explanation: The number 3 appears more than once in the array.
This problem is an extended version of the following problem.
Find the two repeating elements in a given array
Approach 1( Using hashmap):
Use the input array to store the frequency of each element. While Traversing the array, if an element x is encountered then check if its frequency is greater than 1 , then put it in the result array. if result array is empty return -1 else sort the array and return array.
Follow the steps to implement the approach:
- Create an empty unordered map (hashmap) to store the frequency of each element in the array.
- Iterate through the given array.
- For each element in the array, increment its frequency count in the hashmap.
- Iterate through the hashmap.
- For each key-value pair in the hashmap, if the value (frequency count) is greater than 1, add the corresponding key (element) to the result vector.
- If the result vector is empty after step 3, it means no duplicates were found. In this case, add -1 to the result vector.
- Return the result vector containing duplicate elements or -1 if no duplicates were found.
C++
#include <bits/stdc++.h>
using namespace std;
vector<int> duplicates(long long arr[], int n) {
// Step 1: Create an empty unordered map to store
// element frequencies
unordered_map<long long, int> freqMap;
vector<int> result;
// Step 2: Iterate through the array and count element frequencies
for (int i = 0; i < n; i++) {
freqMap[arr[i]]++;
}
// Step 3: Iterate through the hashmap to find duplicates
for (auto& entry : freqMap) {
if (entry.second > 1) {
result.push_back(entry.first);
}
}
// Step 4: If no duplicates found, add -1 to the result
if (result.empty()) {
result.push_back(-1);
}
// step 5: sort the result
sort(result.begin(),result.end());
// Step 6: Return the result vector containing
// duplicate elements or -1
return result;
}
int main() {
long long a[] = {1, 6, 5, 2, 3, 3, 2};
int n = sizeof(a) / sizeof(a[0]);
vector<int> duplicates_found = duplicates(a, n);
cout << "Duplicate elements: ";
for (int element : duplicates_found) {
cout << element << " ";
}
cout << endl;
return 0;
}
Java
import java.util.*;
public class Main {
public static List<Integer> duplicates(long[] arr) {
// Step 1: Create an empty hashmap to store element frequencies
Map<Long, Integer> freqMap = new HashMap<>();
List<Integer> result = new ArrayList<>();
// Step 2: Iterate through the array and count element frequencies
for (long num : arr) {
freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
}
// Step 3: Iterate through the hashmap to find duplicates
for (Map.Entry<Long, Integer> entry : freqMap.entrySet()) {
if (entry.getValue() > 1) {
result.add(Math.toIntExact(entry.getKey()));
}
}
// Step 4: If no duplicates found, add -1 to the result
if (result.isEmpty()) {
result.add(-1);
}
// Step 5: Sort the result
Collections.sort(result);
// Step 6: Return the result list containing duplicate elements or -1
return result;
}
public static void main(String[] args) {
long[] a = {1, 6, 5, 2, 3, 3, 2};
List<Integer> duplicatesFound = duplicates(a);
System.out.print("Duplicate elements: ");
for (int element : duplicatesFound) {
System.out.print(element + " ");
}
System.out.println();
}
}
Python
def duplicates(arr):
# Step 1: Create an empty dictionary to store element frequencies
freq_map = {}
result = []
# Step 2: Iterate through the array and count element frequencies
for num in arr:
freq_map[num] = freq_map.get(num, 0) + 1
# Step 3: Iterate through the dictionary to find duplicates
for key, value in freq_map.items():
if value > 1:
result.append(key)
# Step 4: If no duplicates found, add -1 to the result
if not result:
result.append(-1)
# Step 5: Sort the result
result.sort()
# Step 6: Return the result list containing duplicate elements or -1
return result
if __name__ == "__main__":
a = [1, 6, 5, 2, 3, 3, 2]
duplicates_found = duplicates(a)
print("Duplicate elements:", end=" ")
for element in duplicates_found:
print(element, end=" ")
print()
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static List<int> Duplicates(long[] arr)
{
// Step 1: Create an empty dictionary to store element frequencies
Dictionary<long, int> freqMap = new Dictionary<long, int>();
List<int> result = new List<int>();
// Step 2: Iterate through the array and count element frequencies
foreach (long num in arr)
{
if (freqMap.ContainsKey(num))
freqMap[num]++;
else
freqMap[num] = 1;
}
// Step 3: Iterate through the dictionary to find duplicates
foreach (var entry in freqMap)
{
if (entry.Value > 1)
result.Add((int)entry.Key);
}
// Step 4: If no duplicates found, add -1 to the result
if (result.Count == 0)
result.Add(-1);
// Step 5: Sort the result
result.Sort();
// Step 6: Return the result list containing duplicate elements or -1
return result;
}
static void Main(string[] args)
{
long[] a = { 1, 6, 5, 2, 3, 3, 2 };
List<int> duplicatesFound = Duplicates(a);
Console.Write("Duplicate elements: ");
foreach (int element in duplicatesFound)
{
Console.Write(element + " ");
}
Console.WriteLine();
}
}
JavaScript
function duplicates(arr) {
// Step 1: Create an empty object to store element frequencies
const freqMap = {};
const result = [];
// Step 2: Iterate through the array and count element frequencies
for (let num of arr) {
freqMap[num] = (freqMap[num] || 0) + 1;
}
// Step 3: Iterate through the object to find duplicates
for (let key in freqMap) {
if (freqMap[key] > 1) {
result.push(Number(key));
}
}
// Step 4: If no duplicates found, add -1 to the result
if (result.length === 0) {
result.push(-1);
}
// Step 5: Sort the result
result.sort((a, b) => a - b);
// Step 6: Return the result array containing duplicate elements or -1
return result;
}
const a = [1, 6, 5, 2, 3, 3, 2];
const duplicatesFound = duplicates(a);
console.log("Duplicate elements: " + duplicatesFound.join(" "));
OutputDuplicate elements: 2 3
Time Complexity: O(n Log n), Two traversals are needed. And then sorting. We can avoid sorting and have the time complexity as O(n) if order is not required.
Auxiliary Space: O(n), The extra space is used for the hash and array to be returned.
Approach 2( Using Auxiliary Array):
Since the numbers inside the array range from 0 to n-1 (inclusive), where n is the length of the array, we can utilize an auxiliary array of size n to record the frequency of each element. By iterating through we can found the duplicates easily.
Steps to implement the approach:
1. Range of Numbers: The numbers in the input array are assumed to be within the range 1 to n.
2. Auxiliary Array: We use an auxiliary array of size n+1 to keep track of the frequency of each number.
3. Counting Frequencies: As we iterate through the input array, we increment the count for each number in the auxiliary array.
4. Detecting Duplicates: If the count for any number exceeds 1, we add that number to our list of duplicates.
C++
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int n = nums.size(); // Get the size of the input vector
vector<int> arr(n + 1, 0); // Create an auxiliary vector of size n+1 initialized to 0
vector<int> list; // Vector to store duplicates
// Iterate through each number in the input vector
for (int i : nums) {
if (++arr[i] > 1) // Increment the count for this number and check if it is now a duplicate
list.push_back(i); // If it is a duplicate, add it to the list
}
return list; // Return the list of duplicates
}
};
int main() {
Solution solution;
vector<int> nums = {4, 3, 2, 7, 7, 2, 3, 1};
vector<int> duplicates = solution.findDuplicates(nums);
// Print the duplicates
cout << "Duplicate elements are: ";
for (int num : duplicates) {
cout << num << " "; // Output: 2 3
}
cout << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<Integer> findDuplicates(int[] nums)
{
int n = nums.length; // Get the length of the input
// array
int[] arr = new int[n+1]; // Create an auxiliary
// array of size n+1
List<Integer> list
= new ArrayList<>(); // List to store duplicates
// Iterate through each number in the input array
for (int i : nums) {
if (++arr[i] > 1) // Increment the count for
// this number and check if it is now a duplicate
list.add(i); // If it is a duplicate, add it
// to the list
}
return list; // Return the list of duplicates
}
// Driver Code
public static void main(String[] args)
{
Solution solution = new Solution();
int[] nums = { 4, 3, 2, 7, 7, 2, 3, 1 };
List<Integer> duplicates
= solution.findDuplicates(nums);
System.out.print("Duplicate elements are: ");
for (int num : duplicates) {
System.out.print(num + " ");
}
System.out.println(); // Output: Duplicate elements
// are: 2 3
}
}
Python
class Solution:
def findDuplicates(self, nums):
n = len(nums) # Get the length of the input list
# Create an auxiliary list of size n+1 initialized to 0
arr = [0] * (n+1)
result = [] # List to store duplicates
# Iterate through each number in the input list
for num in nums:
arr[num] += 1 # Increment the count for this number
if arr[num] == 2: # Check if it is now a duplicate
result.append(num) # If it is a duplicate,
# add it to the list
return result # Return the list of duplicates
if __name__ == "__main__":
solution = Solution()
nums = [4, 3, 2, 7, 7, 2, 3, 1]
duplicates = solution.findDuplicates(nums)
print("Duplicate elements are: ", end="")
for num in duplicates:
print(num, end=" ") # Output: 2 3
print()
C#
using System;
using System.Collections.Generic;
public class Solution {
public IList<int> FindDuplicates(int[] nums)
{
int n = nums.Length; // Get the length of the input
// array
int[] arr = new int[n+1]; // Create an auxiliary
// array of size n+1
List<int> list
= new List<int>(); // List to store duplicates
// Iterate through each number in the input array
foreach(int i in nums)
{
if (++arr[i] > 1) // Increment the count for this
// number and check if it is now a duplicate
list.Add(i); // If it is a duplicate, add it
// to the list
}
return list; // Return the list of duplicates
}
public static void Main(string[] args)
{
Solution solution = new Solution();
int[] nums = { 4, 3, 2, 7, 7, 2, 3, 1 };
IList<int> duplicates
= solution.FindDuplicates(nums);
// Print the duplicates
Console.Write("Duplicate elements are: ");
foreach(int num in duplicates)
{
Console.Write(num + " "); // Output: 2 3
}
Console.WriteLine();
}
}
OutputDuplicate elements are: 7 2 3
Time Complexity: O(n), since it iterates through the given array once.. So the time complexity is O(n).
Auxiliary Space: O(n), since we are using an auxiliary array to map frequencies.
All of the above approaches require extra space. Please refer the below article for constant extra space solution.