Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

945. 使数组唯一的最小增量 #31

Open
yankewei opened this issue Mar 22, 2020 · 0 comments
Open

945. 使数组唯一的最小增量 #31

yankewei opened this issue Mar 22, 2020 · 0 comments
Labels
中等 题目难度为中等 数组 题目类型为数组

Comments

@yankewei
Copy link
Owner

yankewei commented Mar 22, 2020

给定整数数组 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
}
@yankewei yankewei added 中等 题目难度为中等 数组 题目类型为数组 labels Mar 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
中等 题目难度为中等 数组 题目类型为数组
Projects
None yet
Development

No branches or pull requests

1 participant