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.
For example:
nums = [1,2,2]
should return 1
. After 1 move, the array could be [1, 2, 3]
.nums = [3,2,1,2,1,7]
should return 6
. 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.Write an efficient algorithm to solve this problem. What is the time and space complexity of your solution? Consider edge cases such as an empty array or an array that is already unique.
One straightforward approach is to iterate through the array and, for each number, check if it already exists earlier in the array. If it does, increment the number until it becomes unique. This process continues until all numbers are unique.
def min_moves_naive(nums):
moves = 0
for i in range(len(nums)):
while nums[i] in nums[:i]:
nums[i] += 1
moves += 1
return moves
To optimize, we can sort the array first. Then, we iterate through the sorted array, ensuring that each number is greater than the previous number by at least 1. If it's not, we increment it to be one greater than the previous, and we accumulate the moves.
def min_moves(nums):
nums.sort()
moves = 0
prev = 0
for i in range(len(nums)):
if i > 0:
prev = nums[i-1]
if nums[i] <= prev:
moves += prev - nums[i] + 1
nums[i] = prev + 1
return moves
The greedy approach works by ensuring that each element nums[i]
is strictly greater than the element before it nums[i-1]
. Sorting the array allows us to process elements in increasing order. If an element is less than or equal to the previous one, we increment it by the minimum amount to make it unique. This strategy minimizes the total number of moves because we are only ever incrementing when necessary to avoid duplicates and maintain uniqueness.