Minimum Increment operations to make Array unique

08 Jul, 2022
Given an array A[] of integers. In one move you can choose any element A[i], and increment it by 1. The task is to return the minimum number of moves needed to make every value in the array A[] unique.Examples:  
Input: A[] = [3, 2, 1, 2, 1, 7]
Output: 6
Explanation:  After 6 moves, the array could be 
[3, 4, 1, 2, 5, 7].
It can be shown that it is impossible for the array 
to have all unique values with 5 or less moves.

Input: A[] = [1, 2, 2]
Output: 1
Explanation: After 1 move [2 -> 3], the array could be [1, 2, 3].
 
A simple solution to make each duplicate value unique is to keep incrementing it repeatedly until it is not unique. However, we might do a lot of extra work, if we have an array of all ones.So, what we can do instead is to evaluate what our increments should be. If for example, we have [1, 1, 1, 3, 5], we don’t need to process all the increments of duplicated 1’s. We could take two ones (taken = [1, 1]) and continue processing. Whenever we find an empty(unused value) place like 2 or 4 we can then recover that our increment will be 2-1, 4-1 respectively.Thus, we first count the values and for each possible value X in the array:  
If there are 2 or more values X in A, save the extra duplicated values to increment later.
If there are 0 values X in A, then a saved value gets incremented to X.
Below is the implementation of the above approach:  
Java
Python3
C#
// Java Implementation of above approachimport java.util.*; class GFG {     // function to find minimum increment required    static int minIncrementForUnique(int[] A)    {        // collect frequency of each element        TreeMap<Integer, Integer> dict            = new TreeMap<Integer, Integer>();        HashSet<Integer> used = new HashSet<Integer>();       // Load Frequency Map (Element -> Count) and Used Set        for (int i : A) {            if (dict.containsKey(i))                dict.put(i, dict.get(i) + 1);            else {                dict.put(i, 1);                used.add(i);            }        }         int maxUsed = 0; // Works for +ve numbers        int ans = 0;         for (Map.Entry<Integer, Integer> entry :             dict.entrySet()) {             int value = entry.getKey();            int freq = entry.getValue();             if (freq <= 1) //If not a duplicate, skip                continue;             int duplicates = freq - 1; // Number of duplicates 1 less than count                     // Start with next best option for this duplicate:          // CurNum + 1 or an earlier maximum number that has been used            int cur = Math.max(value + 1, maxUsed);            while (duplicates > 0) {                if (!used.contains(cur)) {                    ans += cur - value; // Number of increments = Available Spot - Duplicate Value                    used.add(cur);                    duplicates--;                    maxUsed = cur;                }                cur++;            }        }         // return answer        return ans;    }     // Driver code     public static void main(String[] args)    {        int[] A = { 3, 2, 1, 2, 1, 2, 6, 7 };        System.out.print(minIncrementForUnique(A));    }} // This code is contributed by Aditya
# Python3 Implementation of above approachimport collections # function to find minimum increment requireddef minIncrementForUnique(A):     # collect frequency of each element    count = collections.Counter(A)     # array of unique values taken    taken = []     ans = 0     for x in range(100000):        if count[x] >= 2:            taken.extend([x] * (count[x] - 1))        elif taken and count[x] == 0:            ans += x - taken.pop()     # return answer    return ans # Driver codeA = [3, 2, 1, 2, 1, 7]print(minIncrementForUnique(A))
// C# Implementation of above approachusing System;using System.Collections.Generic; class GFG{  // function to find minimum increment requiredstatic int minIncrementForUnique(int []A){      // collect frequency of each element    Dictionary<int,int> mpp = new Dictionary<int,int>();      foreach(int i in A)    {        if(mpp.ContainsKey(i))            mpp[i] = mpp[i] + 1;        else            mpp.Add(i, 1);    }      // array of unique values taken    List<int> taken = new List<int>();      int ans = 0;      for (int x = 0; x < 100000; x++)    {        if (mpp.ContainsKey(x) && mpp[x] >= 2)            taken.Add(x * (mpp[x] - 1));        else if(taken.Count > 0 &&                ((mpp.ContainsKey(x) &&                mpp[x] == 0)||!mpp.ContainsKey(x)))        {            ans += x - taken[taken.Count - 1];            taken.RemoveAt(taken.Count - 1);        }    }      // return answer    return ans;}  // Driver codepublic static void Main(String[] args){      int []A = {3, 2, 1, 2, 1, 7};          Console.Write(minIncrementForUnique(A));}} // This code contributed by PrinciRaj1992
12
Time Complexity: O(n*log(n))Auxiliary Space: O(n) 
mohit kumar 29
Rajput-Ji
princiraj1992
imshubhamkr50
adityanamjoshi
subhammahato348
Arrays
Mathematical
Python Programs
Arrays
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Set in C++ Standard Template Library (STL)
Write a program to print all permutations of a given string
C++ Data Types
Merge two sorted arrays
Operators in C / C++