LEETCODE - 0945 - 使数组唯一的最小增量

268 阅读1分钟

原文链接

查看此题 - 使数组唯一的最小增量

解题思路

先将数组排序,之后比较前后两个数字。 如果后面数字小于等于前面数字,则对后面数字进行 move 操作,并记录次数。

个人感觉通过排序解题不符合这道题 中等 的难度...所以尝试不排序

遍历数组A,记录每个数字出现的次数(ns)和所有数字中的最小值(min)和最大值(max)。

从最小值min开始遍历ns,将出现次数大于1的数字依次向后move ,并记录每次move的次数。

由于题中定义A中数字的区间为[0, 40000],所以在[min(max, 40001), +∞]的区间中不会有重复,可以通过求和公式直接计算。

完整代码

排序

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
}