09 Find duplicates in an array of n + 1 integers

Question

Given an array a[] of size N which contains elements from 0 to N-1, you need to find all the elements occurring more than once in the given array.

Example 1:

Input:
N = 4
a[] = {0,3,1,2}
Output: -1
Explanation: N=4 and all elements from 0
to (N-1 = 3) are present in the given
array. Therefore output is -1.

Example 2:

Input:
N = 5
a[] = {2,3,1,2,3}
Output: 2 3 
Explanation: 2 and 3 occur more than once
in the given array.

Your Task: Complete the function duplicates() which takes array a[] and n as input as parameters and returns a list of elements that occur more than once in the given array in sorted manner. If no such element is found, return list containing [-1].

Expected Time Complexity: O(n). Expected Auxiliary Space: O(n). Note : The extra space is only for the array to be returned. Try and perform all operation withing the provided array.

Constraints: 1 <= N <= 105 0 <= A[i] <= N-1, for each valid i

Using `map`

Logic
  1. Count each element in a map<int, int>

  2. If count is more than one then repeated

    1. store in res

  3. return res

Code
vector<int> duplicates(int arr[], int n) {
    map<int, int> freq;
    for(int i = 0; i < n; i++)
        freq[arr[i]]++;
        
    vector<int> res;
        
    for(pair<int, int> p: freq) 
        if(p.second > 1) 
            res.push_back(p.first);
    
    if(!res.size())
        res.push_back(-1);
    
    return res;
}
Complexity

Time Complexity: O(n)O(n)

Space Complexity: O(n)O(n)

Negation Technique

This won't work. But Why?

The negation of zero doesn't change anything. Some repetitions will be impossible to follow due to the presence of zero. So this technique will not work.

Increment and divide by `n`

Logic
  1. For every number in the array

    1. Use it as an index

      1. Increment the value at that index by n

      2. The number that repeats once will make that index incremet by n only once.

      3. But the number that repeates 2 times will increment that index twice and so on.

  2. Scan the array again

    1. Try dividing each value by n

      1. If it has been incremented by n only once, then the quotient will be [1,2)[1, 2)

      2. If it has been incremented twice then the quotient will be [2,3)[2, 3) and so on.

    2. Every numeber that has a quotient more than 1 has been incremented more than once

      1. This implies that the number appeared more than once.

        1. Insert this value into res

  3. return res

Code
vector<int> duplicates(int arr[], int n) {
     for(int i = 0; i < n; i++)
        arr[arr[i] % n] += n;
        
    vector<int> res;
    
    for(int i = 0; i < n; i++)
        if(arr[i] / n > 1)
            res.push_back(i);
            
    if(res.empty()) 
        res.push_back(-1);
    return res;
}
Complexity

Time Complexity: O(n)O(n)

Space Complexity: O(1)O(1)

Drawbacks: Modifies the given array

Last updated