给定整数数组A []。一键移动可以选择任意元素A [i],并将其递增1。任务是返回使数组A []中的每个值唯一所需的最小移动数。
例子:
Input: A[] = [3, 2, 1, 2, 1, 7]
Output: 6
Explanation: After 6 moves, the array could be
[3, 4, 1, 2, 5, 7].
It can be shown that it is impossible for the array
to have all unique values with 5 or less moves.
Input: A[] = [1, 2, 2]
Output: 1
Explanation: After 1 move [2 -> 3], the array could be [1, 2, 3].
使每个重复值唯一的一种简单解决方案是不断重复增加它,直到它不是唯一的为止。但是,如果我们有一个数组,那么我们可能会做很多额外的工作。
因此,我们可以做的是评估我们的增量应该是多少。例如,如果我们有[1、1、1、3、5],则不需要处理重复的1的所有增量。我们可以取两个(取= [1,1])并继续处理。每当我们找到一个空的(未使用的值)位置(例如2或4)时,我们都可以恢复到增量分别为2-1、4-1。
因此,我们首先对值进行计数,并对数组中每个可能的值X进行计数:
- 如果A中有两个或两个以上的值X,请保存多余的重复值,以便以后增加。
- 如果A中有0个值X,则保存的值将递增到X。
下面是上述方法的实现:
CPP
// C++ Implementation of above approach
#include
using namespace std;
// function to find minimum increment required
int minIncrementForUnique(vector A)
{
// collect frequency of each element
unordered_map mpp;
for(int i:A) mpp[i]++;
// taken is to keep count
// of duplicate items
int taken=0, ans=0;
for (int x = 0; x < 100000; x++)
{
// If number is present
// multiple times
if (mpp[x] >= 2){
taken += mpp[x]-1;
ans -= x*(mpp[x]-1);
}
// If there is no x in the array
else if(taken > 0 and mpp[x] == 0)
{
ans += x;
taken--;
}
}
// return answer
return ans;
}
// Driver code
int main()
{
vector A = {3, 2, 1, 2, 1, 7};
// Function Call
cout << minIncrementForUnique(A);
return 0;
}
// This code is contributed by mohit kumar 29
Java
// Java Implementation of above approach
import java.util.*;
class GFG
{
// function to find minimum increment required
static int minIncrementForUnique(int []A)
{
// collect frequency of each element
HashMap mpp = new HashMap();
for(int i:A)
{
if(mpp.containsKey(i))
mpp.put(i, mpp.get(i) + 1);
else
mpp.put(i, 1);
}
// array of unique values taken
Vector taken =
new Vector();
int ans = 0;
for (int x = 0; x < 100000; x++)
{
// If number is present
// multiple times
if (mpp.containsKey(x) && mpp.get(x) >= 2)
{
taken.add(x * (mpp.get(x)- 1));
}
// If there is no x in the array
else if(taken.size() > 0 &&
((mpp.containsKey(x) &&
mpp.get(x) == 0)||!mpp.containsKey(x)))
{
ans += x - taken.get(taken.size() - 1);
taken.remove(taken.size() - 1);
}
}
// return answer
return ans;
}
// Driver code
public static void main(String[] args)
{
int []A = {3, 2, 1, 2, 1, 7};
System.out.print(minIncrementForUnique(A));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 Implementation of above approach
import collections
# function to find minimum increment required
def minIncrementForUnique(A):
# collect frequency of each element
count = collections.Counter(A)
# array of unique values taken
taken = []
ans = 0
for x in range(100000):
if count[x] >= 2:
taken.extend([x] * (count[x] - 1))
elif taken and count[x] == 0:
ans += x - taken.pop()
# return answer
return ans
# Driver code
A = [3, 2, 1, 2, 1, 7]
print(minIncrementForUnique(A))
C#
// C# Implementation of above approach
using System;
using System.Collections.Generic;
class GFG
{
// function to find minimum increment required
static int minIncrementForUnique(int []A)
{
// collect frequency of each element
Dictionary mpp = new Dictionary();
foreach(int i in A)
{
if(mpp.ContainsKey(i))
mpp[i] = mpp[i] + 1;
else
mpp.Add(i, 1);
}
// array of unique values taken
List taken = new List();
int ans = 0;
for (int x = 0; x < 100000; x++)
{
if (mpp.ContainsKey(x) && mpp[x] >= 2)
taken.Add(x * (mpp[x] - 1));
else if(taken.Count > 0 &&
((mpp.ContainsKey(x) &&
mpp[x] == 0)||!mpp.ContainsKey(x)))
{
ans += x - taken[taken.Count - 1];
taken.RemoveAt(taken.Count - 1);
}
}
// return answer
return ans;
}
// Driver code
public static void Main(String[] args)
{
int []A = {3, 2, 1, 2, 1, 7};
Console.Write(minIncrementForUnique(A));
}
}
// This code contributed by PrinciRaj1992
输出:
6
时间复杂度: O(N)