LeetCode 945使数组唯一的最小增量

LeetCode 945使数组唯一的最小增量

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

  • 输入:[1,2,2] 输出:1 解释:经过一次 move 操作,数组将变为 [1, 2, 3]。

    输入:[3,2,1,2,1,7] 输出:6 解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。

  • 思路:先排序后遍历,时间复杂度O(nlogn)

    首先将数组进行排序,然后从左到右遍历数组:

    • 如果当前元素大于等于上一个元素,保持不变;
    • 如果当前元素小于上一个元素,就需要增加当前元素,直到大于上一个元素。
    • 最后的当前数字变的至少比前面的数字大1

    例如输入[3,2,1,2,1,7],排序后[1, 1, 2, 2, 3, 7],move操作后 [1, 2, 3, 4, 5, 7]

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int n = A.size(), res = 0;

        sort(A.begin(), A.end());
        //排序后A[i-1]一定小于等于A[i]    
        for(int i = 1; i < n; i++)
        {
            //如果A[i-1]小于A[i]则不需要记录操作A[i]也保持不变
            if(A[i-1] < A[i])
            {
                res += 0;
                A[i] += 0;
            }
            //如果A[i-1]等于A[i]则需要记录操作并将A[i]更新值比原先大1
            else if(A[i-1] == A[i])
            {
                res += 1;
                A[i] += 1;
            }
            //在更新过程中会将排序打乱,出现A[i-1]大于A[i]的情况
            else
            {
                res += A[i-1] - A[i] + 1;
                A[i] += A[i-1] - A[i] + 1;
            }
            /*
            if(A[i-1] >= A[i])//等价于上面的三个逻辑
            {
                res += A[i-1] - A[i] + 1;
                A[i] += A[i-1] - A[i] + 1;
            }
            */
        }
        
        return res;
    }
};
//优化写法二:
class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int n = A.size(), res = 0;

        sort(A.begin(), A.end());
        //排序后A[i-1]一定小于等于A[i]
        for(int i = 1; i < n; i++)
        {
            //diff表示后者需要比前者大1,所要进行的操作次数
            int diff = A[i-1] - A[i] + 1;
            res += max(0, diff);
            A[i] += max(0, diff);
        }
        return res;
    }
};
//优化写法三:
class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int n = A.size(), curmax = 0, res = 0;

        sort(A.begin(), A.end());
        for(int i = 0; i < n; i++)
        {
            //如果A[i]<curmax表示A[i]在前边出现过了
            //需要将A;[i]增加到curmax,然后自加1
            if(A[i] < curmax) res += curmax - A[i];
            //否则A[i]可用,并更新curmax为A[i]+1
            else curmax = A[i];
            curmax++;
        }
        return res;
    }
};

贪心+并查集解法:

Minimum Increment to Make Array Unique

贪心算法、并查集(Java)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值