leetcode 945. Minimum Increment to Make Array Unique 使数组唯一的最小增量 排序/计数
leetcode 2020年3月 每日一题打卡
题目:
给定整数数组 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique
思路:
- 排序:先排序,再依次遍历数组元素,若当前元素小于等于它前一个元素,则将其变为前一个数+1。时间复杂度就是排序的时间复杂度O(nlogn)。
- 计数的思想,第一遍遍历计数,第二遍遍历计数数组,若当前数字的个数num大于1个,则只留下1个,其他的num-1个后移,空间换时间。时间复杂度O(n)。
细节:
- 计数的坑在于计数的时候,空间换时间,要开80000的数组。
- python内置函数sort()的时间复杂度为O(nlogn),空间复杂度为O(n),内部实现机制为Timesort。
代码:
# 自己提交的代码
class Solution(object):
def minIncrementForUnique(self, A):
"""
:type A: List[int]
:rtype: int
"""
# 最坏情况A中有40000个数,每个数都是39999,那么count=[0]*40000是不够的。应该是约为count=[0]*80000
count=[0]*80000 #count[i]表示A中i的个数
excess=[] #表示A中个数不为1 的数字
move=0
for i in range(0,len(A)):
count[A[i]]+=1
if count[A[i]]>1:
excess.append(A[i])
excess=list(set(excess))
excess.sort()
nexcess=len(excess)
np=nexcess
for i in range(0,len(count)):
if np==0:
break
if count[i]==0 and i>excess[nexcess-np]:
move+=i-excess[nexcess-np]
count[excess[nexcess-np]]-=1
if count[excess[nexcess-np]]==1:
np-=1
return move
class Solution {
public int minIncrementForUnique(int[] A) {
// 先排序
Arrays.sort(A);
int move = 0;
// 遍历数组,若当前元素小于等于它的前一个元素,则将其变为前一个数+1
for (int i = 1; i < A.length; i++) {
if (A[i] <= A[i - 1]) {
int pre = A[i];
A[i] = A[i - 1] + 1;
move += A[i] - pre;
}
}
return move;
}
}
作者:sweetiee
链接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique/solution/ji-shu-onxian-xing-tan-ce-fa-onpai-xu-onlogn-yi-ya/
来源:力扣(LeetCode)
本博客为原创作品,欢迎指导,转载请说明出处,附上本文链接,谢谢