LEETCODE - 0945 - 使數組惟一的最小增量

原文連接數組

查看此題 - 使數組惟一的最小增量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
}
複製代碼