避免整数数组中的重复整数

时间:2012-06-06 07:19:21

标签: java arrays int duplicates

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

7 个答案:

答案 0 :(得分:2)

解决方案取决于您的要求。如果你有一个小的数组大小(n <10 ^ 6),那么在每次插入时扫描数组就足够了,但是如果你有一个大数组并经常插入,我会提出一个不同的解决方案。

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

如果你需要性能并且内存不是你的约束,你可以采用一个布尔数组并将所有元素初始化为 false 。然后,只要你得到一个数字,就把它在布尔数组中的索引值设为 true ,然后插入时,检查被插入元素的索引号处的布尔值。

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

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 ,该元素存在于数组中,请勿插入。

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

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

P.S:基本上是内存与性能之间的权衡,这就是通用计算权交易,无处不在。

答案 1 :(得分:1)

如果您的问题是要返回Integer[]而不是任何其他集合,则可以使用Set<Integer> private来避免重复值,然后返回{{1} }。

这是最简单的恕我直言......

例如:

Set<Integer>.toArray(new Integer[0])

答案 2 :(得分:1)

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

如果数字范围有一个小范围,这个解决方案很有效。注意,我的例子也假设整数是正数。一些优化是使用long []数组并将每个位用作标志。

答案 3 :(得分:1)

我建议您首先执行 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);
}

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

答案 4 :(得分:0)

  

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

在插入之前检查数组,

您可以使用insertion sort并执行binarysearch它会更快

答案 5 :(得分:0)

  1. 编写一个将值添加到数组的方法。
  2. 在添加之前,如果值存在,则扫描数组。
  3. 如果确实存在,请跳过添加。
  4. 仅使用 该方法为数组添加值。
  5. 理想情况下,将数组和方法捆绑在一个类中。 Voila:封装!

答案 6 :(得分:0)

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

只需循环检查每个值即可。如此

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

    }

如果必须重新分配Array,那么你必须这样做:

    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;

    }