class Solution:
def minIncrementForUnique(self, nums):
nums.sort()
moves = 0
for i in range(1, len(nums)):
if nums[i] <= nums[i-1]:
increment = nums[i-1] + 1 - nums[i]
nums[i] = nums[i-1] + 1
moves += increment
return moves
class Solution {
public:
int minIncrementForUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
int moves = 0;
for (int i = 1; i < nums.size(); ++i) {
if (nums[i] <= nums[i-1]) {
moves += nums[i-1] + 1 - nums[i];
nums[i] = nums[i-1] + 1;
}
}
return moves;
}
};
class Solution {
public int minIncrementForUnique(int[] nums) {
Arrays.sort(nums);
int moves = 0;
for (int i = 1; i < nums.length; i++) {
if (nums[i] <= nums[i - 1]) {
moves += nums[i - 1] + 1 - nums[i];
nums[i] = nums[i - 1] + 1;
}
}
return moves;
}
}
var minIncrementForUnique = function(nums) {
nums.sort((a, b) => a - b);
let moves = 0;
for (let i = 1; i < nums.length; i++) {
if (nums[i] <= nums[i - 1]) {
moves += nums[i - 1] + 1 - nums[i];
nums[i] = nums[i - 1] + 1;
}
}
return moves;
};
Given an array of integers nums
, you are allowed to increment any element by 1 any number of times. Your goal is to make every value in nums
unique, using the minimum total number of increments across all elements.
Return the minimum number of increments needed to make the array unique. Each increment operation increases an element by exactly 1, and no two elements can have the same value after all operations are performed.
nums
(array of integers, possibly with duplicates)At first glance, it seems we could simply check for duplicates and increment them until they're unique. However, this can become inefficient if there are many duplicates or large gaps between numbers.
A naive brute-force approach would be, for every element, to check if it's already present in the array and increment it until it becomes unique. But this is slow, especially for large arrays, because each check and increment can take a lot of time.
Instead, we can optimize by sorting the array first. This way, duplicates or numbers that would cause conflicts are adjacent, making it much easier to identify and resolve collisions in one pass. By always comparing each number to its immediate predecessor, we can efficiently determine whether an increment is needed.
The key realization is that, after sorting, if nums[i]
is less than or equal to nums[i-1]
, we must increment nums[i]
to be one greater than nums[i-1]
to maintain uniqueness.
This approach is efficient because sorting is O(n log n)
and the single pass is O(n)
. No extra data structures are needed beyond the input array.
Let's consider the input nums = [3, 2, 1, 2, 1, 7]
.
[1, 1, 2, 2, 3, 7]
O(n^2)
(lots of repeated checks/increments).O(1)
extra, but inefficient in time.O(n log n)
O(n)
O(n log n)
O(1)
(if sorting in-place), otherwise O(n)
if a copy is made.The optimized method is much faster for large arrays because it avoids repeated scanning and uses sorting to cluster duplicates.
To make an array unique with the minimum number of increments, sort the array and then increment any value that is less than or equal to its predecessor. This ensures each value is unique with the least effort. The key insight is that sorting makes it easy to identify and fix conflicts in one efficient pass, leading to a simple and elegant O(n log n)
solution.