【问题标题】:Avoiding duplicate integers in an integer array避免整数数组中的重复整数
【发布时间】:2012-06-10 04:58:42
【问题描述】:

如何在不使用任何集合(即 Arraylist 或 Set 等)的情况下避免将重复整数添加到整数数组中?

【问题讨论】:

  • 您必须 (1) 与数组一起使用另一个集合(即哈希)或 (2) 每次添加元素时执行线性搜索。
  • 你不能使用any of the collections i.e. Arraylist or Set?还是只需要返回一个整数数组?
  • 这是homework吗?如果是这样,最好将其标记为这样。

标签: java arrays int duplicates


【解决方案1】:

解决方案取决于您的要求。如果你有一个小的数组大小(n,在每次插入时扫描数组就足够了,但是如果你有一个大数组并且频繁插入,我会提出一个不同的解决方案。

在每次插入时扫描数组将需要 O(n) 的复杂度。对于小数字,开销可以忽略不计,但随着数组大小的增加,每次插入的遍历效率都很低。

如果您需要性能并且内存不是您的限制,您可以使用一个布尔数组并将所有元素初始化为 false。然后每当得到一个数字时,将其在布尔数组中的索引值设为true,并在插入时检查该布尔值是否在被插入元素的索引号处。

这里是初始化布尔数组的代码(初始化它会使所有元素都为假):

boolean [] duplicateValuesArray = new boolean[Integer.MAX_VALUE];

这是在数组中插入元素的函数:

    public void insertElement(int elementToBeInserted) {
        if(!duplicateValuesArray[elementToBeInserted])  //check if element already in array
            duplicateValuesArray[elementToBeInserted] = true;
            mainArray[index++] = elementToBeInserted;
    }

这样,每当你得到一个数字,布尔数组中那个索引的值就会被设置为true,并且在插入时,每次检查索引,如果值是true ,该元素存在于数组中,请勿插入。

如果你有一个大的 ma​​inArray (n>10^6) 并且你有频繁的插入,那么这个复杂度会低得多。这是因为,初始化一个布尔数组是一次 O(n) 复杂度,之后,检查布尔数组中的元素并插入元素只是 O(1) 操作,在恒定时间内发生。

因此有效的复杂性被降低到仅仅初始化布尔数组。即使在内存占用方面,我也不介意,因为布尔基元只占用内存中的一位。

P.S:基本上这是内存与性能的权衡,这就是通用计算的权衡,随处可见。

【讨论】:

    【解决方案2】:

    如果您的问题是返回一个Integer[],而不是任何其他集合,那么您可以使用Set<Integer>privately 来避免重复值,然后返回Set<Integer>.toArray(new Integer[0])

    恕我直言,这是最简单的方法......

    例如:

    private Set<Integer> intSet = new HashSet<Integer>();
    
    public void setIntArray(Integer[] i){
        intSet = new HashSet<Integer>(Arrays.asList(i));
    }
    
    public Integer[] getIntArray(){
        return intSet.toArray(new Integer[0]);
    }
    

    【讨论】:

      【解决方案3】:

      您可以创建另一个布尔类型的数组,我们称之为exists。然后每次将整数添加到主列表时,检查 exists[newNumber]。如果值为真,则它已经存在,否则将数字添加到整数数组并将布尔值设置为真。

      如果数字范围的界限很小,此解决方案效果很好。请注意,我的示例还假设整数是正数。一些优化是使用 long[] 数组并将每个位用作标志。

      【讨论】:

        【解决方案4】:

        我建议你先执行 Arrays.Sort(int[])。然后使用 Arrays.binarySearch( int [] ,int ) 来检查元素是否存在。

        根据javadoc:

        /**
         * Sorts the specified array of ints into ascending numerical order.
         * The sorting algorithm is a tuned quicksort, adapted from Jon
         * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
         * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
         * 1993).  This algorithm offers n*log(n) performance on many data sets
         * that cause other quicksorts to degrade to quadratic performance.
         *
         * @param a the array to be sorted
         */
        public static void sort(int[] a) {
        sort1(a, 0, a.length);
        }
        

        对于 BinarySearch:

         /**
         * Searches the specified array of ints for the specified value using the
         * binary search algorithm.  The array must be sorted (as
         * by the {@link #sort(int[])} method) prior to making this call.  If it
         * is not sorted, the results are undefined.  If the array contains
         * multiple elements with the specified value, there is no guarantee which
         * one will be found.
         *
         * @param a the array to be searched
         * @param key the value to be searched for
         * @return index of the search key, if it is contained in the array;
         *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
         *         <i>insertion point</i> is defined as the point at which the
         *         key would be inserted into the array: the index of the first
         *         element greater than the key, or <tt>a.length</tt> if all
         *         elements in the array are less than the specified key.  Note
         *         that this guarantees that the return value will be &gt;= 0 if
         *         and only if the key is found.
         */
        public static int binarySearch(int[] a, int key) {
        return binarySearch0(a, 0, a.length, key);
        }
        

        而且你知道元素是否存在,休息对你来说很容易。

        【讨论】:

          【解决方案5】:

          不使用任何集合,即 Arraylist 或 Set 等?

          在插入之前检查数组,

          您可以使用insertion sort 并执行binarysearch 会快一点

          【讨论】:

            【解决方案6】:
            1. 编写一个将值添加到数组的方法。
            2. 添加之前,扫描数组是否存在值。
            3. 如果确实存在,请跳过添加。
            4. 使用该方法向数组添加值。
            5. 理想情况下,将数组和方法捆绑在一个类中。瞧:封装!

            【讨论】:

              【解决方案7】:

              首先假设数组是一个缓冲区并且有额外的空间。

              只需循环检查每个值。比如

                  for(int i=0;  i<endpointer  &&i < buffer.length  ; i++){
                      if(buffer[i]==valueToPutInArray){
                          valueExists=true;
                          break;
                      }
                  }
                  if(!valueExists)    {
                      buffer[endpointer++]=valueToPutInArray;
              
                  }
              

              如果必须重新分配数组,那么您必须执行以下操作:

                  int i=0;
                  Integer[] outputArray = new Integer[buffer.length+1];
                  for(Integer value : buffer) {
                      if(value==valueToPutInArray){
                          valueExists=true;
                          break;
                      }
                      outputArray[i++]=value;
                  }
                  if(!valueExists)    {
                      outputArray[i]=valueToPutInArray;
              
                  }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2019-05-24
                • 2011-06-02
                • 2019-05-07
                • 1970-01-01
                • 2014-10-29
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多