Open In App

Find duplicates in O(n) time and O(1) extra space | Set 1

Improve
Improve
Like Article
Like
Save
Share
Report

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:

Modify the array elements by making visited elements negative (if visited once) or greater than n (if visited twice or more).

Follow the steps to implement the approach:

  • Iterate Through the Array
    • Calculate an index based on the absolute value of each element.
    • If the index is equal to ‘n,‘ count it as the largest element.
    • If the element at the calculated index is negative, add (index – 1) to the result vector and modify the element at that index.
    • If there are more than one largest elements, add ‘n – 1’ to the result vector.
  • If the result vector is empty, add ‘-1‘ to it.
  • Otherwise, sort the result vector.
  • Return the Result Vector

Below is the implementation of above approach:

C++
#include <bits/stdc++.h>
using namespace std;

vector<int> duplicates(int arr[], int n)
{

    // Increment array elements by 1
    for (int i = 0; i < n; i++) {
        arr[i] += 1;
    }

    // result vector
    vector<int> res;

    // count variable for count of
    // largest element
    int count = 0;

    for (int i = 0; i < n; i++) {

        // Calculate index value
        int index = abs(arr[i]) > n ? abs(arr[i]) / (n + 1)
                                    : abs(arr[i]);

        // Check if index equals largest element value
        if (index == n) {
            count++;
            continue;
        }

        // Get element value at index
        int val = arr[index];

        // Check if element value is negative, positive
        // or greater than n
        if (val < 0) {
            res.push_back(index - 1);
            arr[index] = abs(arr[index]) * (n + 1);
        }
        else if (val > n)
            continue;
        else
            arr[index] = -arr[index];
    }

    // If largest element occurs more than once
    if (count > 1)
        res.push_back(n - 1);

    if (res.size() == 0)
        res.push_back(-1);
    else
        sort(res.begin(), res.end());

    return res;
}

// Driver Code
int main()
{
    int numRay[] = { 0, 4, 3, 2, 7, 8, 2, 3, 1 };
    int n = sizeof(numRay) / sizeof(numRay[0]);

    vector<int> ans = duplicates(numRay, n);
    for (int i : ans)
        cout << i << ' ' << endl;
    return 0;
}
Java
// Java Code for above approach
import java.util.*;

public class Solution {
  static ArrayList<Integer> duplicates(int arr[], int n)
  {

    // Increment array elements by 1
    for (int i = 0; i < n; i++) {
      arr[i] += 1;
    }

    // result list
    ArrayList<Integer> res = new ArrayList<>();

    // count variable for count of
    // largest element
    int count = 0;

    for (int i = 0; i < n; i++) {

      // Calculate index value
      int index = Math.abs(arr[i]) > n
        ? Math.abs(arr[i]) / (n + 1)
        : Math.abs(arr[i]);

      // Check if index equals largest element value
      if (index == n) {
        count++;
        continue;
      }

      // Get element value at index
      int val = arr[index];

      // Check if element value is negative, positive
      // or greater than n
      if (val < 0) {
        res.add(index - 1);
        arr[index] = Math.abs(arr[index]) * (n + 1);
      }
      else if (val > n)
        continue;
      else
        arr[index] = -arr[index];
    }

    // If largest element occurs more than once
    if (count > 1)
      res.add(n - 1);

    if (res.size() == 0)
      res.add(-1);
    else
      Collections.sort(res);

    return res;
  }

  // Driver Code
  public static void main(String[] args)
  {
    int numRay[] = { 0, 4, 3, 2, 7, 8, 2, 3, 1 };
    int n = numRay.length;
    ArrayList<Integer> ans = duplicates(numRay, n);
    for (Integer i : ans) {
      System.out.println(i);
    }
  }
}
// This code is contributed by karandeep1234
Python
# Python3 code for above approach
def duplicates(arr, n):
  
    # Increment array elements by 1
    for i in range(n):
        arr[i] = arr[i] + 1
        
    # result vector
    res = []
    
    # count variable for count of
    # largest element
    count = 0
    for i in range(n):
      
        # Calculate index value
        if(abs(arr[i]) > n):
            index = abs(arr[i])//(n+1)
        else:
            index = abs(arr[i])
            
        # Check if index equals largest element value
        if(index == n):
            count += 1
            continue
            
        # Get element value at index
        val = arr[index]
        
        # Check if element value is negative, positive
        # or greater than n
        if(val < 0):
            res.append(index-1)
            arr[index] = abs(arr[index]) * (n + 1)
        elif(val>n):
            continue
        else:
            arr[index] = -arr[index]
            
    # If largest element occurs more than once
    if(count > 1):
        res.append(n - 1)
    if(len(res) == 0):
        res.append(-1)
    else:
        res.sort()
    return res
  
# Driver Code
numRay = [ 0, 4, 3, 2, 7, 8, 2, 3, 1 ]
n = len(numRay)
ans = duplicates(numRay,n)
for i in ans:
    print(i)
    
 # This code is contributed by Vibhu Karnwal
C#
// C# Code for above approach

using System;
using System.Collections.Generic;

public class HelloWorld {

  public static List<int> duplicates(int[] arr, int n)
  {
    // Increment array elements by 1
    for (int i = 0; i < n; i++) {
      arr[i] += 1;
    }

    // result vector
    List<int> res = new List<int>();

    // count variable for count of
    // largest element
    int count = 0;

    for (int i = 0; i < n; i++) {

      // Calculate index value
      int index = Math.Abs(arr[i]) > n
        ? Math.Abs(arr[i]) / (n + 1)
        : Math.Abs(arr[i]);
      // Check if index equals largest element value
      if (index == n) {
        count++;
        continue;
      }

      // Get element value at index
      int val = arr[index];

      // Check if element value is negative, positive
      // or greater than n
      if (val < 0) {
        res.Add(index - 1);
        arr[index] = Math.Abs(arr[index]) * (n + 1);
      }
      else if (val > n)
        continue;
      else
        arr[index] = -1 * arr[index];
    }

    // If largest element occurs more than once
    if (count > 1)
      res.Add(n - 1);

    if (res.Count == 0)
      res.Add(-1);
    else
      res.Sort();

    return res;
  }

  // Driver Code
  public static void Main(string[] args)
  {
    int[] numRay = { 0, 4, 3, 2, 7, 8, 2, 3, 1 };
    int n = numRay.Length;

    List<int> ans = duplicates(numRay, n);
    for (int i = 0; i < ans.Count; i++) {
      Console.WriteLine(ans[i]);

    }

  }
}

// This code is contributed by adityamaharshi21 
JavaScript
// JS code for above approach
function duplicates(arr, n) {

    // Increment array elements by 1
    for (let i = 0; i < n; i++) {
        arr[i] += 1;
    }

    // result vector
    let res = new Array();

    // count variable for count of
    // largest element
    let count = 0;

    for (let i = 0; i < n; i++) {

        // Calculate index value
        let index = Math.abs(arr[i]) > n ? Math.abs(arr[i]) / (n + 1)
            : Math.abs(arr[i]);

        // Check if index equals largest element value
        if (index == n) {
            count++;
            continue;
        }

        // Get element value at index
        let val = arr[index];

        // Check if element value is negative, positive
        // or greater than n
        if (val < 0) {
            res.push(index - 1);
            arr[index] = Math.abs(arr[index]) * (n + 1);
        }
        else if (val > n)
            continue;
        else
            arr[index] = -arr[index];
    }

    // If largest element occurs more than once
    if (count > 1)
        res.push(n - 1);

    if (res.length == 0)
        res.push(-1);
    else
        res.sort(function (a, b) { return a - b });

    return res;
}

// Driver Code
let numRay = [0, 4, 3, 2, 7, 8, 2, 3, 1];
let n = numRay.length;

let ans = duplicates(numRay, n);
for (let i = 0; i < ans.length; i++)
    console.log(ans[i]);

// This code is contributed by adityamaharshi21 

Output
2 
3 

Time Complexity: O(n), Only two traversals are needed. If the answer to be return should in ascending order, then in that case we will have to sort the list and complexity will become O(n logn).
Auxiliary Space: O(1). The extra space is used only for the array to be returned.

Approach 2:

Use the input array to store the frequency of each element. While Traversing the array, if an element x is encountered then increase the value of x%n‘th index by n. The original value at ith index can be retrieved by arr[i]%n and frequency can be retrieved by dividing the element by n.

Follow the steps to implement the approach:

  • Traverse the given array from start to end.
  • For every element in the array increment the element arr[i] by n.
  • Now traverse the array again and store all those indexes i for which arr[i]/n is greater than 1. Which guarantees that the number has appeared more than once.
  • Since, the values are getting modified, the original value at ith index can be retrieved by arr[i]%n.

Below is the implementation of above approach:

C++
#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

vector<int> duplicates(int arr[], int n) {
    unordered_map<int, int> frequency; // Hash table to store frequency of elements
    vector<int> duplicates;

    // Count the frequency of each element
    for (int i = 0; i < n; ++i) {
        frequency[arr[i]]++;
    }

    // Check for elements with frequency greater than 1 (duplicates)
    for (auto& pair : frequency) {
        if (pair.second > 1) {
            duplicates.push_back(pair.first);
        }
    }

    return duplicates;
}

int main() {
    int arr[] = { 1, 6, 3, 1, 3, 6, 6 };
    int arr_size = sizeof(arr) / sizeof(arr[0]);

    cout << "The repeating elements are: \n";

    // Function call
    vector<int> ans = duplicates(arr, arr_size);
    if (ans.empty()) {
        cout << "No duplicates found." << endl;
    } else {
        for (auto x : ans) {
            cout << x << " ";
        }
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    public static List<Integer> duplicates(int[] arr) {
        Map<Integer, Integer> frequency = new HashMap<>();
        List<Integer> duplicates = new ArrayList<>();

        // Count the frequency of each element
        for (int num : arr) {
            frequency.put(num, frequency.getOrDefault(num, 0) + 1);
        }

        // Check for elements with frequency greater than 1 (duplicates)
        for (Map.Entry<Integer, Integer> entry : frequency.entrySet()) {
            if (entry.getValue() > 1) {
                duplicates.add(entry.getKey());
            }
        }

        return duplicates;
    }

    public static void main(String[] args) {
        int[] arr = {1, 6, 3, 1, 3, 6, 6};
        
        List<Integer> ans = duplicates(arr);
        if (ans.isEmpty()) {
            System.out.println("No duplicates found.");
        } else {
            System.out.println("The repeating elements are:");
            for (int num : ans) {
                System.out.print(num + " ");
            }
        }
    }
}
Python
def duplicates(arr):
    frequency = {}
    duplicates = []

    # Count the frequency of each element
    for num in arr:
        frequency[num] = frequency.get(num, 0) + 1

    # Check for elements with frequency greater than 1 (duplicates)
    for key, value in frequency.items():
        if value > 1:
            duplicates.append(key)

    return duplicates

arr = [1, 6, 3, 1, 3, 6, 6]
ans = duplicates(arr)
if not ans:
    print("No duplicates found.")
else:
    print("The repeating elements are: " + ' '.join(map(str, ans)))
C#
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static List<int> Duplicates(int[] arr)
    {
        Dictionary<int, int> frequency = new Dictionary<int, int>();
        List<int> duplicates = new List<int>();

        // Count the frequency of each element
        foreach (int num in arr)
        {
            if (frequency.ContainsKey(num))
                frequency[num]++;
            else
                frequency[num] = 1;
        }

        // Check for elements with frequency greater than 1 (duplicates)
        foreach (var pair in frequency)
        {
            if (pair.Value > 1)
            {
                duplicates.Add(pair.Key);
            }
        }

        return duplicates;
    }

    static void Main(string[] args)
    {
        int[] arr = {1, 6, 3, 1, 3, 6, 6};

        List<int> ans = Duplicates(arr);
        if (ans.Count == 0)
        {
            Console.WriteLine("No duplicates found.");
        }
        else
        {
            Console.WriteLine("The repeating elements are:");
            foreach (int num in ans)
            {
                Console.Write(num + " ");
            }
        }
    }
}
JavaScript
function duplicates(arr) {
    let frequency = new Map();
    let duplicates = [];

    // Count the frequency of each element
    arr.forEach(num => {
        frequency.set(num, (frequency.get(num) || 0) + 1);
    });

    // Check for elements with frequency greater than 1 (duplicates)
    frequency.forEach((value, key) => {
        if (value > 1) {
            duplicates.push(key);
        }
    });

    return duplicates;
}

let arr = [1, 6, 3, 1, 3, 6, 6];
let ans = duplicates(arr);
if (ans.length === 0) {
    console.log("No duplicates found.");
} else {
    console.log("The repeating elements are:", ...ans);
}

Output
The repeating elements are: 
3 6 1 

Time Complexity: O(n), Only two traversals are needed. So the time complexity is O(n).
Auxiliary Space: O(1), The extra space is used only for the array to be returned.



Last Updated : 26 Mar, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads