原文连接数组
查看此题 - 使数组惟一的最小增量markdown
先将数组排序,以后比较先后两个数字。 若是后面数字小于等于前面数字,则对后面数字进行 move 操做,并记录次数。oop
我的感受经过排序解题不符合这道题 中等 的难度...因此尝试不排序post
遍历数组A,记录每一个数字出现的次数(ns)和全部数字中的最小值(min)和最大值(max)。spa
从最小值min开始遍历ns,将出现次数大于1的数字依次向后move ,并记录每次move的次数。code
因为题中定义A中数字的区间为[0, 40000],因此在[min(max, 40001), +∞]的区间中不会有重复,能够经过求和公式直接计算。orm
func MinIncrementForUnique(A []int) int { sort.Ints(A) l := len(A) n := 0 for i := 1; i < l; i++ { if A[i] <= A[i-1] { m := A[i-1] - A[i] + 1 A[i] += m n += m } } 复制代码
// IntMax 32位最大有符号整数 const IntMax = 1<<31 - 1 // IntMin 32位最小有符号整数 const IntMin = ^IntMax func minIncrementForUnique(A []int) int { if len(A) == 0 { return 0 } ns := [40001]int{} // ns := map[int]int{} max := IntMin min := IntMax for _, n := range A { ns[n]++ if n > max { max = n } if n < min { min = n } } move := 0 for i := min; i <= max; i++ { if ns[i] > 1 { n := ns[i] - 1 move += n ns[i+1] += n } } n := ns[max+1] - 1 move += (1 + n) * n / 2 return move } 复制代码