945. 使数组唯一的最小增量
给定整数数组 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
思路
实在不想自己再写一遍排序,就用了sort()排序。
用这个排序接口需要实现Len(),Less(),Swap()。
关于操作次数的计数有一个技巧,例如有个3重复了,我们不必急于知道这个3要移动到哪里,只需要让总操作数-3,加入我们后面发现在8这个位置可以放,再把总操作数+8。
我的解答
type is []int
func (a is) Len() int {
return len(a)
}
func (a is) Less(i, j int) bool {
return a[i] < a[j]
}
func (a is) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func minIncrementForUnique(A []int) int {
if len(A) < 2 {
return 0
}
sort.Sort(is(A))
taken, incre := 0, 0 //taken表示重复元素个数,incre表示总操作数
for i := 1; i < len(A); i++ {
if A[i] == A[i-1] {
taken++
incre = incre - A[i]
} else {
minn := 0
if taken < A[i]-A[i-1] { //尝试在A[i]~A[i-1]空挡间插数
minn = taken
} else {
minn = A[i] - A[i-1] - 1
}
incre = incre + minn*A[i-1] + minn*(minn+1)/2
taken = taken - minn
}
}
return incre+A[len(A)-1]*taken+taken*(taken+1)/2
}