美文网首页算法代码
使数组唯一的最小增量

使数组唯一的最小增量

作者: windUtterance | 来源:发表于2020-05-15 11:54 被阅读0次

题目描述
给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1。
返回使 A 中的每个值都是唯一的最少操作次数。

示例
输入:[3,2,1,2,1,7]
输出:6
解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。
可以看出 5 次或 5 次以下的 move 操作是不能让数组的每个值唯一的。

Java代码

class Solution {
    //先排序,再依次遍历数组元素,若当前元素小于等于它前一个元素,则将其变为前一个数 +1。
    public int minIncrementForUnique1(int[] A) {
        if(A.length == 0) return 0;
        Arrays.sort(A);
        int move = 0;

        for(int i = 1;i < A.length;i++) {
            if(A[i] <= A[i - 1]) {
                int  pre = A[i];
                A[i] = A[i - 1] + 1;
                move += A[i] - pre;
            }
        }
        return move;
    }

    //线性探测(含路径压缩)
    int[] pos = new int[80000];

    public int minIncrementForUnique(int[] A) {
        if(A.length == 0) return 0;
        Arrays.fill(pos, -1); //-1表示空位
        int move = 0;

        //遍历每个数字a对其进行寻址得到位置b,b-a的增量就是操作数
        for(int a : A) {
            int b = findPos(a);
            move += b - a;
        }

        return move;
    }

    private int findPos(int a) {
        int b = pos[a];

        //如果当前为是空位,直接将a插入空位
        if(b == -1) {
            pos[a] = a;
            return a;
        } else {
            //否则向后寻址,因为pos中标记了上次寻址得到的空位
            //所以直接从pos[a]+1开始寻址即可
            b = findPos(b + 1);
            
            //寻址后的新空位要重新赋值给pos[a],压缩路径体现在这里
            pos[a] = b;
            return b;
        }
    }
}

相关文章

网友评论

    本文标题:使数组唯一的最小增量

    本文链接:https://www.haomeiwen.com/subject/gspqohtx.html