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

参考了,leetcode官方题解的方法,使用计数的方式

算法

首先统计出每个数出现的次数,然后从小到大遍历每个数 x

如果 x 出现了两次以上,就将额外出现的数记录下来(例如保存到一个列表中);

如果 x 没有出现过,那么在记录下来的数中选取一个 v,将它增加到 x,需要进行的操作次数为 x - v

我们还可以对该算法进行优化,使得我们不需要将额外出现的数记录下来。还是以 [1, 1, 1, 1, 3, 5] 为例,当我们发现有 3 个重复的 1 时,我们先将操作次数减去 1 + 1 + 1。接下来,当我们发现 246 都没有出现过时,我们依次将操作次数增加 24 6.

注意事项

虽然 A[i] 的范围为 [0, 40000),但我们有可能会将数据递增到 40000 的两倍 80000。这是因为在最坏情况下,数组 A 中有 4000040000,这样要使得数组值唯一,需要将其递增为 [40000, 40001, ..., 79999],因此用来统计的数组需要开到 80000

class Solution {
    public int minIncrementForUnique(int[] A) {
        int[] count = new int[80001];
        for (int i=0;i<A.length;i++)
            count[A[i]]++;
        int repeat = 0;//count[i]大于等于2的位置
        int empty = 0;//count[i]为0 的位置
        int cnt = 0;//重复数字的个数
        for (int i = 0; i <= 80000; i++) {
            if(count[i] >= 2){
               repeat += (count[i]-1) * i;
               cnt+= count[i] - 1;
            }else if(count[i] == 0 && cnt > 0){
                empty += i;
                cnt--;
            }
        }
        return empty - repeat;
    }

    public static void main(String[] args) {
        int[] arr = {2,2,2,1};
        System.out.println(new Solution().minIncrementForUnique(arr));
    }
}

原文地址:https://www.cnblogs.com/HoweZhan/p/12545501.html

时间: 2024-10-11 10:50:21

Leetcode 945 使数组唯一的最小增量的相关文章

【Leetcode】使数组唯一的最小增量(每日一题)

题目链接:使数组唯一的最小增量 题意:给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1. 返回使 A 中的每个值都是唯一的最少操作次数. 题解: 1.暴力sort.O(nlogn).排序以后,如果当前数字<=前一个数字,那么就把当前的数字变成前一个数字+1. 增量就是A[i-1]+1-A[i].遍历以后的结果就是要求的最小增量.跑了80ms 2.用一个数组表示hash.空间换时间.O(n). 我们对hash数组进行移动操作,每次对hash[i]>1的数字进行操作,只

使数组唯一的最小增量

题目描述: 给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1. 返回使 A 中的每个值都是唯一的最少操作次数. 我的思路: 先对数组进行排序,重复的数一定排在一起,再对重复的数进行move操作若A[i]小于A[i+1],说明前后两数唯一,不做额外操作若A[i]与A[i+1]相同,则对A[i+1]进行一次move操作,使前后两数唯一若A[i]大于A[i+1],说明A[i]进行过一次以上move操作,需要对A[i+1]进行多一次的move操作才可使两数唯一,而需要进行的m

LeetCode 945. Minimum Increment to Make Array Unique

945. Minimum Increment to Make Array Unique (使数组唯一的最小增量) 链接 https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique 题目 给定整数数组 A,每次 move 操作将会选择任意?A[i],并将其递增?1. 返回使 A?中的每个值都是唯一的最少操作次数. 示例 1: 输入:[1,2,2] 输出:1 解释:经过一次 move 操作,数组将变为 [1, 2,

Leetcode 462.最少移动次数使数组元素相等

最少移动次数使数组元素相等 给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1. 您可以假设数组的长度最多为10000. 例如: 输入: [1,2,3] 输出: 2 说明: 只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1): [1,2,3] => [2,2,3] => [2,2,2] 排序之后,从两边往中间走,最大和最小之间的差距,是一定要填补上的,不管+1 还是 -1,所以最后都等于中位数. 1 import java.uti

量数组交换差最小算法

交换两个数组值使两个数组之差最小 有两个序列a,b,大小都为n,序列元素的值任意整数,无序: 要求:通过交换a,b 中的元素,使[序列a 元素的和]与[序列b 元素的和]之间的差最小. 例如: var a=[100,99,98,1,2, 3]; var b=[1, 2, 3, 4,5,40]; 假设序列a,b中元素的和为sum_a和sum_b.假设aa和bb分别为序列a,b中的元素,则交换aa,bb后序列的和变为sum_a-aa+bb,sum_b+aa-bb: 两序列的差为(sum_a-aa+b

Effective Item 9 - 尽量使可访问性最小化

模块设计是否良好,有个重要的因素在于,相对外部模块是否隐藏内部数据以及实现细节. 设计良好的模块会隐藏实现细节,并将API与其实现隔离开来. 模块之间通过API进行通信,对于内部工作情况互不可见. 即,封装(encapsulation)--软件设计的基本原则之一. 为什么要封装? 通过封装可以有效地接触各个模块之间的耦合关系,使这些模块可以独立地开发.测试.优化.使用.理解和修改. 即: ·可以增加开发效率,模块可以并行开发. ·封装可以减轻维护的负担,可以更有效的进行优化,且不会影响其他模块的

LeetCode:删除排序数组中的重复项||【80】

LeetCode:删除排序数组中的重复项||[80] 题目描述 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1: 给定 nums = [1,1,1,2,2,3], 函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 . 你不需要考虑数组中超出新长度后面的元素. 示例 2: 给定 nums =

旋转数组,求最小元素

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 如果,要求在排序的数组中查找一个数字或者统计某个数字出现的次数,都可以尝试二分查找算法 分析: 旋转之后的数组实际上可以划分成两个有序的子数组:前面子数组的大小都大于后面子数组中的元素 注意到实际上最小的元素就是两个

[经典面试题]排序数组中绝对值最小元素

[题目] 题目为: 有一个已经排序的数组(升序),数组中可能有正数.负数或0,求数组中元素的绝对值最小的数,要求,不能用顺序比较的方法(复杂度需要小于O(n)),可以使用任何语言实现 例如,数组{-20,-13,-4, 6, 77,200} ,绝对值最小的是-4. [分析] 给定数组是已经排好序的,且是升序,没有重复元素. 一个简单的思路,就是一次性遍历数组,求出数组的元素的绝对值的最小值,这样的时间复杂度为O(n). 但是,这样就浪费了题目的一个条件:数组是已经排好序的.所以,需要对原来的题目