945. 使数组唯一的最小增量
题目描述
给你一个整数数组 nums
。每次 move 操作将会选择任意一个满足 0 <= i < nums.length
的下标 i
,并将 nums[i]
递增 1
。
返回使 nums
中的每个值都变成唯一的所需要的最少操作次数。
生成的测试用例保证答案在 32 位整数范围内。
示例 1:
输入:nums = [1,2,2] 输出:1 解释:经过一次 move 操作,数组将变为 [1, 2, 3]。
示例 2:
输入:nums = [3,2,1,2,1,7] 输出:6 解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。 可以看出 5 次或 5 次以下的 move 操作是不能让数组的每个值唯一的。
提示:
1 <= nums.length <= 105
0 <= nums[i] <= 105
解法
方法一:排序 + 贪心
我们首先对数组 \(\textit{nums}\) 进行排序,用一个变量 \(\textit{y}\) 记录当前的最大值,初始时 \(\textit{y} = -1\)。
然后遍历数组 \(\textit{nums}\),对于每个元素 \(x\),我们将 \(y\) 更新为 \(\max(y + 1, x)\),并将操作次数 \(y - x\) 累加到结果中。
遍历完成后,返回结果即可。
时间复杂度 \(O(n \times \log n)\),空间复杂度 \(O(\log n)\)。其中 \(n\) 是数组 \(\textit{nums}\) 的长度。
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 |
|
1 2 3 4 5 6 7 8 9 |
|
方法二:计数 + 贪心
根据题目描述,结果数组的最大值 \(m = \max(\textit{nums}) + \textit{len}(\textit{nums})\),我们可以使用一个计数数组 \(\textit{cnt}\) 来记录每个元素出现的次数。
然后从 \(0\) 到 \(m - 1\) 遍历,对于每个元素 \(i\),如果它出现的次数 \(\textit{cnt}[i]\) 大于 \(1\),那么我们将 \(\textit{cnt}[i] - 1\) 个元素增加到 \(i + 1\),并将操作次数累加到结果中。
遍历完成后,返回结果即可。
时间复杂度 \(O(m)\),空间复杂度 \(O(m)\)。其中 \(m\) 是数组 \(\textit{nums}\) 的长度加上数组的最大值。
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|