每日一题-22
题目描述
使数组唯一的最小增量
给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1。
返回使 A 中的每个值都是唯一的最少操作次数。
示例 1:
输入:[1,2,2]
输出:1
解释:经过一次 move 操作,数组将变为 [1, 2, 3]。
示例 2:
输入:[3,2,1,2,1,7]
输出:6
解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。
可以看出 5 次或 5 次以下的 move 操作是不能让数组的每个值唯一的。
提示:
0 <= A.length <= 40000
0 <= A[i] < 40000
解题思路
1.贪心,每次达到局部最优,最后收敛于整体最优。
- 先对数组进行排序
- 比较前后两个元素的大小。若后面元素小于前面元素,将后面元素递增到前面元素+1.
时间复杂度O(nlogn),因为主要操作在于排序
2.计数排序
- 设置一个hash表,大小为40001(数组最长为40000)
- 先找出数组的最大值,遍历从0到最大值的hash表。若当前元素出现次数大于1,则只保留一个,其他元素全部+1,移到后一位
- 遍历结束后,Max+1存储的出现次数往后移动,只需用求和公式计算,不必一直移动。
代码
class Solution: def minIncrementForUnique(self, A: List[int]) -> int: # A.sort() # res = 0 # for i in range(1, len(A)): # if A[i]<=A[i-1]: # res += A[i-1]-A[i]+1 # A[i] = A[i-1]+1 # return res # hashTable hashTable = [0]*40001 Max = -1 res = 0 for x in A: hashTable[x] += 1 Max = max(Max, x) for x in range(Max+1): if hashTable[x]>1: hashTable[x+1] += hashTable[x]-1 res += hashTable[x]-1 d = hashTable[Max+1]-1 res += ((1+d)*d)//2 return res