使数组唯一的最小增量--数学思维的运用

0x01.问题

给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1
返回使 A 中的每个值都是唯一的最少操作次数。
输入示例:[3,2,1,2,1,7]
输出示例:6
解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。
提示:0 <= A.length <= 40000 0 <= A[i] < 40000

C++函数形式为      int minIncrementForUnique(vector<int>& A)

0x02.简要分析

刚看到这个问题,肯定有点懵,因为假如有相同的就加1的话,加1之后还可能与其它的数相同,继续加,依然有可能在哪个角落有一个数就重复了,所以,这样单纯的扫描数组,看起来可行型不大。

困扰我们的问题主要是什么呢?

就是,你不知道加完之后,哪个数会和这个数相同,要是我们能把相同的找出来就好了。

于是,思路来了,排序!!!

排序后,相同的肯定都在一起,如果加1,也可以根据下一个数来判断是否冲突,这样,这个麻烦的问题就解决了,然后,我们仔细思考一下具体思路:

排序后,如果A[i]==A[i-1],说明这里重复了,那么最简单的办法就是A[i]+1

如果A[i]<A[i-1]呢?为什么,会出现这个情况呢,因为在前面相等的条件下,前面的数可能变大了,那么这个时候最好的办法还是A[i]=A[i-1]+1,操作数就是A[i-1]-A[i]+1

为什么我们要说最简单的方法就是保持后一个比前一个大呢?

因为对于一个数组来说,全部不重复的理想条件就是后一个刚好比前一个大1,我们的目的就是创造这个理想条件。

注意:

  • 其实源数组的值其实是在不断的被改变的,这样,我们就可以保证不重复了。
  • 不要轻易的去排序,排序的目的一定是排完序后,可以更加方便的解决问题,不然反而会造成时间的浪费。
  • 默认是升序,C++底层实现是插入排序和快速排序搭配使用。

0x03.解决代码–排序后解决

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int ans=0;
        sort(A.begin(),A.end());
        for(int i=1;i<A.size();i++){
            if(A[i]<=A[i-1]){
                ans+=A[i-1]-A[i]+1;
                A[i]=A[i-1]+1;
            }
        }
        return ans;
    }
};

ATFWUS --Writing By 2020–03–22

  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATFWUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值