题目描述
给定整数数组 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
解题思路
最初想到的使散列+线性探测,但是最坏的情况是O(N^2),优化时间复杂度为O(NlogN)
散列+线性探查
int minIncrementForUnique(vector<int>& A) {
int len = A.size();
if(len <= 1) return 0;
int hash[100005] = {0};
int ops = 0;
for(int i=0;i<len;i++){
if(hash[A[i]] == 1){
int j = A[i];
while(j<100005 && hash[j] == 1) j++;
hash[j] = 1;
ops += j - A[i];
}else hash[A[i]] = 1;
}
return ops;
}
排序+遍历
int minIncrementForUnique(vector<int>& A) {
int len = A.size();
if(len <= 1) return 0;
int ops = 0;
sort(A.begin(),A.end());
for(int i=0;i<len-1;i++){
if(A[i+1] <= A[i]){
int nw = A[i] + 1;
ops += nw - A[i+1];
A[i+1] = nw;
}
}
return ops;
}