每日一题:945. 使数组唯一的最小增量(使用dfs溢出待改进)

给定整数数组 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

解题思路:
将A排序后放在B[40000]数组里,然后利用A的值作为下标,如果B大于等于2说明有重复值,使这个B++,直到没有重复为止
第一版 通过44 / 59 个通过测试用例 栈溢出

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int nums=0;
        dfs(A,nums);
        return nums;
    }
    void dfs(vector<int>& A,int &nums){
        sort(A.begin(),A.end());
        int B[40000];
        memset(B,0,sizeof(B));
        for(int i=0;i<A.size();i++){
            B[A[i]]++;
            if(B[A[i]]==2){
                A[i]++;
                nums++;
                dfs(A,nums);
            }
            if(i==A.size()-1){
                return;
            }
        }
    }
};

第二版 53 / 59 个通过测试用例

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int nums=0;
        sort(A.begin(),A.end());
        int B[40000];
        memset(B,0,sizeof(B));
        for(int i=0;i<A.size();i++){
            B[A[i]]++;
        }
       //int index=0;
        dfs(A,nums,B);
        return nums;
    }
    void dfs(vector<int>& A,int &nums,int B[]){
        for(int i=0;i<A.size();i++){
            if(B[A[i]]>=2){
                B[A[i]]--;
                B[A[i]+1]++;
                A[i]++;
                nums++;
                dfs(A,nums,B);
            }
        }
    }
};

第三版,因为dfs中每次都是从i=0开始,所以添加index作为下标
54 / 59 个通过测试用例

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int nums=0;
        sort(A.begin(),A.end());
        int B[40000];
        memset(B,0,sizeof(B));
        for(int i=0;i<A.size();i++){
            B[A[i]]++;
        }
       int index=0;
        dfs(A,nums,B,index);
        return nums;
    }
    void dfs(vector<int>& A,int &nums,int B[],int index){
        for(int i=index;i<A.size();i++){
            if(B[A[i]]>=2){
                B[A[i]]--;
                B[A[i]+1]++;
                A[i]++;
                nums++;
                index=i;
                dfs(A,nums,B,index);
            }
        }
    }
};

第四版,因为每次都是一个一个的进行检验,但是因为对A进行过排序,如果有多个重复数字,他们也是在一起,所以可以在一遍循环内就对其进行修改
54 / 59 个通过测试用例

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int nums=0;
        sort(A.begin(),A.end());
        int B[40000];
        memset(B,0,sizeof(B));
        for(int i=0;i<A.size();i++){
            B[A[i]]++;
        }
       int index=0;
        dfs(A,nums,B,index);
        return nums;
    }
    void dfs(vector<int>& A,int &nums,int B[],int index){
        for(int i=index;i<A.size();i++){
            if(B[A[i]]>=2){
                B[A[i]+1]=B[A[i]+1]+B[A[i]]-1;
                for(int j=i+1;j<i+B[A[i]];j++){//将除了第i个之后的元素全部进行加一
                nums++;
                A[j]++;
                }
                index=i+1;
                B[A[i]]=1;
                dfs(A,nums,B,index);
            }
        }
    }
};

最终解决方案,进行排序后,前后进行比较,后面的数如果大于等于前面的数,就要变成比前面一个数大一

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int count=0;
        sort(A.begin(),A.end());
        for (int i = 1; i < A.size(); ++i) {
            int nums=0;
               if(A[i]<=A[i-1])
               {
                   nums=A[i-1]-A[i]+1;//操作次数
                   A[i]+=nums;
                   count+=nums;
               }       
        }
        return count;
    }
};
发布了70 篇原创文章 · 获赞 39 · 访问量 2263

猜你喜欢

转载自blog.csdn.net/weixin_45221477/article/details/105028363