945. Minimum Increment to Make Array Unique

问题:

给定数组,给数组的一些值+1作为一个move,使得该数组成为一个没有重复元素的递增数组,

求最小的move。

Example 1:
Input: [1,2,2]
Output: 1
Explanation:  After 1 move, the array could be [1, 2, 3].

Example 2:
Input: [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 with 5 or less moves that it is impossible for the array to have all unique values.
 

Note:
0 <= A.length <= 40000
0 <= A[i] < 40000

  

解法1:

需要两个游标,一个遍历数组元素 i,一个遍历数组中没有的值 j

前提,构成cout数组,记录A每个元素出现的个数。(才能有上面的两个游标遍历)

 

♻️构建cout数组的同时,记录A的最大值maxA,这样遍历数组元素 i 的时候,只需要遍历到这个最大值即可,

不需要遍历完整个40001个元素。

 

数组元素 i 的移动条件是:元素 i 不重复。即不需要进行move

                                  一直找到需要move的 i

非数组元素 j 的移动条件是:j 在数组中,cout[j]!=0 或者 当前的 j 小于 i,那么没法+1
                                  一直找到不再数组中的 j:cout[j]==0 j 是 i要+1移动到的 j

 

找到这样的 i 和 j 后,

结果即是 i 和 j 的差值,即为 i 到 j ,move的次数。

同时 i 的个数-1;

 

代码参考:

 1 class Solution {
 2 public:
 3     int minIncrementForUnique(vector<int>& A) {
 4         int cout[40001]={0};
 5         int i=0,j=0;
 6         int res=0;
 7         int maxA=0;
 8         for(int a:A){
 9             cout[a]++;
10             maxA=max(a,maxA);
11         }
12         while(i<=maxA){
13             while(i<=maxA && cout[i]<=1) i++;
14             while(i>j || j<=maxA && cout[j]!=0) j++;
15             if(i<=maxA){
16                 res+=(j-i);
17                 cout[i]--;
18                 j++;
19             }
20         }
21         return res;
22     }
23 };

 

解法2:

递归寻找法:

构建寻找 i 所要move 到的 j的一个数据结构 visited。visited[i]=j

遍历数组A,第一次访问到元素 a 的时候,将 i 加入到 visited,且记录当前的 i 需要move 到的是 a(自己)。

那么它的move=j-i;

第二次访问到 a 的时候,在visited中找到了a,即visited[a]=a ,存在在visited中,

那么需要尝试下一个数字:(从当前记录的上次最新查找对象 j 开始+1 去尝试)j+1=visited[a]+1=a+1

如果这次尝试的对象 j+1 还是存在在visited中,递归继续去尝试visited[j+1]上记录的下一个尝试对象+1

一直找到不存在这样的 尝试结果k。返回。

那么它的move=k-i

 

代码参考:

 1 class Solution {
 2 public:
 3     unordered_map<int, int> visited;
 4     //visited[i]=j: 对于A的元素值i,要变换的下一个值应该为j
 5     int minIncrementForUnique(vector<int>& A) {
 6         int res=0;
 7         for(int a:A){
 8             res+=find(a)-a;
 9         }
10         return res;
11     }
12     int find(int a){
13         if(visited.count(a)!=0) visited[a]=find(visited[a]+1);
14         else visited[a] = a;
15         return visited[a];
16     }
17 };

 

posted @ 2020-05-26 15:15  habibah_chang  阅读(227)  评论(0编辑  收藏  举报