给定整数数组 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique
解答
排序+遍历
只要排好序,把每个元素和前一个元素比较,在前一个元素的基础上+1-当前的元素,也就是A[i-1] + 1 - A[i]
func minIncrementForUnique(A []int) int {
var ret int
sort.Ints(A)
for i, v := range A {
if i == 0 {
continue
}
if v > A[i-1] {
continue
}
A[i] = A[i-1] + 1
ret += (A[i-1]+1-v)
}
return ret
}
func main() {
fmt.Println(minIncrementForUnique([]int{3, 2, 1, 2, 1, 7})) // 6
}
计数(超时)
func minIncrementForUnique(A []int) int {
var ret int
length := len(A)
m := make(map[int]bool, length)
for _, v := range A {
if _, e := m[v]; !e {
m[v] = true
continue
}
temp := v
for {
temp++
if _, e := m[temp]; !e {
ret += (temp-v)
m[temp] = true
break
}
}
}
return ret
}
计数+状态压缩
上边的计数的方式会超时,是因为进行了很多的检查,例如:A数组中有40000个1,然后我遍历到最后一个元素,我都需要从1往上加,加到40000才发现这个位置是空的。
func minIncrementForUnique(A []int) int {
var ret int
slice := make([]int, 80000)
for i, _ := range slice {
slice[i] = -1
}
for _, v := range A {
b := findPos(slice, v)
ret += b - v
}
return ret
}
func findPos(s []int, a int) int {
if s[a] == -1 {
s[a] = a
return a
}
b := findPos(s, s[a]+1)
s[a] = b
return b
}
给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1。
返回使 A 中的每个值都是唯一的最少操作次数。
示例 1:
示例 2:
提示:
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique
解答
排序+遍历
只要排好序,把每个元素和前一个元素比较,在前一个元素的基础上+1-当前的元素,也就是
A[i-1] + 1 - A[i]计数(超时)
计数+状态压缩
上边的计数的方式会超时,是因为进行了很多的检查,例如:
A数组中有40000个1,然后我遍历到最后一个元素,我都需要从1往上加,加到40000才发现这个位置是空的。