leetcode---945. 使数组唯一的最小增量

在这里插入图片描述


方法一:暴力,对于数组中的每一个数使其递增到数组里不存在的数为止,每增一次计数加一。

int minIncrementForUnique(vector<int>& A) {
    int vis[90005]={0},cont = 0;
    for(int i = 0;i < A.size();i++)
    {
        vis[A[i]]++;
    }
    for(int i = 0;i < A.size();i++)
    {
        if(vis[A[i]] == 1)
            continue;
        int num = A[i];
        do{
            num++;
            cont++;
        }while(vis[num] != 0);
        vis[num] = 1;
        vis[A[i]]--;
    }
    return cont;
}




方法二:对每个数字进行计数,遍历计数数组,把出现1次以上的数放在a数组中,当遍历到空缺位置时,可在a数组中任选一个数字使其递增到该数。该方法对方法一进行了优化,避免我们每次都要重新遍历找一个空缺位置。

int minIncrementForUnique(vector<int>& A) {
    int vis[80000]={0},a[40001];
    for(auto i:A) vis[i]++;
    int cont = 0,cnt = 0,j = 0;
    for(int i = 0;i < 80000;i++)
    {
        while(vis[i] > 1)
        {
            a[cnt++] = i;
            vis[i]--;
        }
        if(j < cnt && vis[i] == 0){
            cont += i-a[j++];
        }
    }
    return cont;
}




方法三:其实对于方法二我们并不需要一个额外的数组来存放重复的数字,我们可以设置一个变量来存放有总共由有多少个数字重复(用于确定我们需要多少个空位),并且对于一个重复的数来说我们可以直接从操作数中减去    重复数字的个数*该数    (因为我们每找到一个数组中不存在的数时,我们需要将重复的数字递增为该数,操做次数等于:数组中不存在的数-重复的数,若我们先将重复的数减去,当我们找到的一个  数组中不存在的数时,只需使操作数加该数,这样做的好处是我们不需要关心将哪个重复的数字递增到我们所找到的  数组中不存在的数,我们只用关心我们是否将所有重复的数字操作完)

int minIncrementForUnique(vector<int>& A) {
    int vis[80000]={0};
    for(auto i:A) vis[i]++;
    int cont = 0,cnt = 0;
    for(int i = 0;i < 80000;i++)
    {
        if(vis[i] > 1)
        {
            cnt += vis[i]-1;
            cont -= (vis[i]-1)*i;
        }
        else if(cnt > 0 && vis[i] == 0){
            cont += i;
            cnt--;
        }
    }
    return cont;
}




方法四:排序。题目要求数组里的数字不能重复,那我们先将数组排序,再使其完全递增。

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




方法五:可以将这道题看成给你一堆数,将他们存放在数组中,这就类似于解决hash冲突(使用线性探测法+路径压缩),每一个数的操作次数为实际存放的位置减去本该存放的位置,贴出大佬题解链接----->膜拜大佬

int vis[80000];
int minIncrementForUnique(vector<int>& A) {
    int cont = 0;
    fill(vis,vis+80000,-1);
    for(auto i:A)
    {
        int b = find(i);
        cont += b-i;
    }
    return cont;
}
int find(int a)
{
    if(vis[a] == -1)
    {
        vis[a] = a;
        return a;
    }
    int b = find(vis[a]+1);
    vis[a] = b;
    return b;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章