zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    2012年决胜HTML5 十四大Web预测盘点
    王海波:Discuz! X 社区功能架构
    史应生:Linux操作系统的性能优化技术
    虚拟还原原理解析
    金山张宴:PHP在金山游戏运营中的应用
    java方法的参数传递
    java逻辑连接词总结
    java名称命名规范
    java引用包的两种方式
    java信息的封装和隐藏
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/12965801.html
Copyright © 2011-2022 走看看