{x}
blog image

Minimum Increment to Make Array Unique

You are given an integer array nums. In one move, you can pick an index i where 0 <= i < nums.length and increment nums[i] by 1.

Return the minimum number of moves to make every value in nums unique.

The test cases are generated so that the answer fits in a 32-bit integer.

 

Example 1:

Input: nums = [1,2,2]
Output: 1
Explanation: After 1 move, the array could be [1, 2, 3].

Example 2:

Input: nums = [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.

 

Constraints:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 105

Solution Explanation for Minimum Increment to Make Array Unique

This problem asks for the minimum number of moves needed to make all elements in an array unique by incrementing elements. Two efficient solutions are presented: Sorting + Greedy and Counting + Greedy.

Solution 1: Sorting + Greedy

This approach leverages sorting to simplify the process of making elements unique.

Algorithm:

  1. Sort the array: Sort the input array nums in ascending order. This ensures we process elements from smallest to largest.

  2. Iterate and track maximum: Initialize a variable y to -1 (representing the highest value seen so far). Iterate through the sorted array. For each element x:

    • Update y to the maximum of y + 1 and x. This ensures that the current element will be at least y + 1 after potential increments.
    • Add y - x to the total increment count (ans). This represents the number of increments needed to make x unique.
  3. Return the total: After iterating through all elements, ans holds the minimum number of increments.

Time Complexity: O(n log n) due to the sorting step. The iteration is O(n).

Space Complexity: O(log n) if an in-place sorting algorithm is used. Otherwise, O(n) for some sorting algorithms.

Solution 2: Counting + Greedy

This approach utilizes a counting array to efficiently track element frequencies and perform the necessary increments.

Algorithm:

  1. Determine maximum possible value: Calculate m = max(nums) + len(nums). This represents the maximum value an element could have after all increments.

  2. Count occurrences: Create a counting array cnt of size m initialized to zeros. Iterate through nums and increment cnt[x] for each element x.

  3. Iterate and increment: Iterate through cnt from index 0 up to m - 1. For each index i:

    • If cnt[i] > 1, it means there are duplicate values of i. Increment cnt[i+1] by cnt[i] - 1 (number of extra occurrences) to shift those duplicates to the next higher value. Add cnt[i] - 1 to ans to account for the number of increments performed.
  4. Return total increments: ans contains the total minimum increments.

Time Complexity: O(m), where m = max(nums) + len(nums). In the worst case, m could be large compared to n, making this potentially less efficient than the sorting approach if the maximum value in nums is significantly larger than the length of nums.

Space Complexity: O(m) to store the counting array.

Code Examples (Python):

Solution 1 (Sorting + Greedy):

class Solution:
    def minIncrementForUnique(self, nums: List[int]) -> int:
        nums.sort()
        ans = 0
        y = -1
        for x in nums:
            y = max(y + 1, x)
            ans += y - x
        return ans
 

Solution 2 (Counting + Greedy):

from collections import Counter
 
class Solution:
    def minIncrementForUnique(self, nums: List[int]) -> int:
        m = max(nums) + len(nums)
        cnt = Counter(nums)
        ans = 0
        for i in range(m):
            if cnt[i] > 1:
                diff = cnt[i] - 1
                cnt[i+1] += diff  #shift duplicates
                ans += diff       #add increments
        return ans

Both solutions achieve the same result, but their efficiency depends on the characteristics of the input array (the range of values versus the number of elements). The sorting approach is generally preferred for its better average-case time complexity unless the maximum value in the input array is extremely large.