• [leetCode]945.使数组唯一的最小增量


    在这里插入图片描述

    排序 + 遍历计数

    我的思路是对数组进行排序,然后对排序后的数组从前向后进行遍历。如果出现重复数字则将其递增,同时记录操作次数。

    class Solution {
        public int minIncrementForUnique(int[] A) {
            int count = 0;
            Arrays.sort(A);
            for(int i = 0; i < A.length; i++){
                int j = i + 1;
                while(j < A.length && A[j] <= A[i]){
                    ++A[j];
                    ++count;
                }
            }
            return count;
        }
    }
    

    计数

    首先统计A中重复数字出现的次数、

    • 如果该数字x出现两次以上则记录多余数字出现的次数,并减去这些多余数字
    • 如果该数字未出现则加上该数字
    class Solution {
        public int minIncrementForUnique(int[] A) {
            //定义一个数组对A中重复数字进行计数,由于A<=40000,最坏情况下A中数字会递增到79999;
            int[] count =  new int[80000];
            for( int x : A)count[x]++;
    
            int ans = 0;//记录答案
            int taken = 0;//记录多余数字出现的次数
    
            for(int x = 0; x < count.length; x++){
                if(count[x]>=2){//如果该数字在A中重复出现
                    //多余数字出现的次数为:
                    taken += count[x] - 1;
                    //ans先减去这些多余重复的数字
                    ans -= x *(count[x] - 1);
                }else if(taken > 0 && count[x] == 0){//如果该数字为出现过
                    //ans加上该未出现过的数字
                    ans+=x;
                    //多余数字减1
                    --taken;
                }
            }
            return ans;
        }
    }
    

    排序

    对数组进行排序,将多余数字变为区间中的数字

    class Solution {
        public int minIncrementForUnique(int[] A) {
            //对数组进行排序
            Arrays.sort(A);
            int ans = 0;//记录答案
            int taken = 0;//记录多余的数字
            for(int i = 1; i < A.length; i++){
                if(A[i] == A[i-1]){
                    //多余的数字加1,
                    ++taken;
                    //ans减去该重复数字
                    ans -= A[i];
                }else {//i指针已经跳过了重复数字,区间{A[i-1]+1~A[i]-1}中的数字是未出现过的,将重复数字变为次区间的数
                    int give = Math.min(A[i] - A[i-1] - 1, taken);//区间范围有限因此应取最小值
                    //give*(give+1)/2为等差数列求和
                    ans+= give * (A[i-1]) + give*(give+1)/2;
                    taken -=give;
                }
            }
            if(taken > 0){//如果还有多余的数字则变为区间{A[A.length-1]] +1~正无穷}之间的数字
                ans += taken * (A[A.length-1]) + taken*(taken+1)/2;
            }
            return ans;
        }
    }
    
  • 相关阅读:
    uniDAC 8.4.1一个严重的bug
    Delphi Event Bus进阶(三)如何使用通道?
    从delphi 10.3到delphi 10.4的改变实务
    uniDAC 8.4.1 database is locked
    调整Delphi IDE代码的行间距
    Deployment Manager now Open Source
    Delphi 10.4.2 Android 64位发布格式之App Bundle格式aab
    每日日报79
    每日日报78
    团队冲刺博客(四)
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13859991.html
Copyright © 2020-2023  润新知