如何在不使用Set的情况下有效地从数组中删除重复项

时间:2013-07-31 09:50:29

标签: java arrays optimization

我被要求编写自己的实现来删除数组中的重复值。这就是我创造的。但经过1,000,000个元素的测试后,需要很长时间才能完成。我可以做些什么来改进我的算法或删除任何错误?

我需要编写自己的实现 - 而不是use SetHashSet等。或者任何其他工具,如迭代器。只需一个数组即可删除重复项。

public static int[] removeDuplicates(int[] arr) {

    int end = arr.length;

    for (int i = 0; i < end; i++) {
        for (int j = i + 1; j < end; j++) {
            if (arr[i] == arr[j]) {                  
                int shiftLeft = j;
                for (int k = j+1; k < end; k++, shiftLeft++) {
                    arr[shiftLeft] = arr[k];
                }
                end--;
                j--;
            }
        }
    }

    int[] whitelist = new int[end];
    for(int i = 0; i < end; i++){
        whitelist[i] = arr[i];
    }
    return whitelist;
}

47 个答案:

答案 0 :(得分:34)

您可以借助设置集合

int end = arr.length;
Set<Integer> set = new HashSet<Integer>();

for(int i = 0; i < end; i++){
  set.add(arr[i]);
}

现在,如果您将遍历此,它将仅包含唯一值。迭代代码是这样的:

Iterator it = set.iterator();
while(it.hasNext()) {
  System.out.println(it.next());
}

答案 1 :(得分:14)

注意:我假设数组已排序。

代码:

int[] input = new int[]{1, 1, 3, 7, 7, 8, 9, 9, 9, 10};
int current = input[0];
boolean found = false;

for (int i = 0; i < input.length; i++) {
    if (current == input[i] && !found) {
        found = true;
    } else if (current != input[i]) {
        System.out.print(" " + current);
        current = input[i];
        found = false;
    }
}
System.out.print(" " + current);

输出:

  1 3 7 8 9 10

答案 2 :(得分:7)

通过删除最里面的for循环,对原始代码本身进行轻微修改。

public static int[] removeDuplicates(int[] arr){
    int end = arr.length;

    for (int i = 0; i < end; i++) {
        for (int j = i + 1; j < end; j++) {
            if (arr[i] == arr[j]) {                  
                /*int shiftLeft = j;
                for (int k = j+1; k < end; k++, shiftLeft++) {
                    arr[shiftLeft] = arr[k];
                }*/
                arr[j] = arr[end-1];
                end--;
                j--;
            }
        }
    }

    int[] whitelist = new int[end];
    /*for(int i = 0; i < end; i++){
        whitelist[i] = arr[i];
    }*/
    System.arraycopy(arr, 0, whitelist, 0, end);
    return whitelist;
}

答案 3 :(得分:7)

由于您可以假设范围在0-1000之间,因此有一个非常简单有效的解决方案

//Throws an exception if values are not in the range of 0-1000
public static int[] removeDuplicates(int[] arr) {
    boolean[] set = new boolean[1001]; //values must default to false
    int totalItems = 0;

    for (int i = 0; i < arr.length; ++i) {
        if (!set[arr[i]]) {
            set[arr[i]] = true;
            totalItems++;
        }
    }

    int[] ret = new int[totalItems];
    int c = 0;
    for (int i = 0; i < set.length; ++i) {
        if (set[i]) {
            ret[c++] = i;
        }
    }
    return ret;
}

这以线性时间O(n)运行。警告:返回的数组已排序,如果这是非法的,则此答案无效。

答案 4 :(得分:6)

class Demo 
{
    public static void main(String[] args) 
    {
        int a[]={3,2,1,4,2,1};
        System.out.print("Before Sorting:");
        for (int i=0;i<a.length; i++ )
        {
            System.out.print(a[i]+"\t");
        }
        System.out.print ("\nAfter Sorting:");
        //sorting the elements
        for(int i=0;i<a.length;i++)
        {
            for(int j=i;j<a.length;j++)
            {
                if(a[i]>a[j])
                {
                    int temp=a[i];
                    a[i]=a[j];
                    a[j]=temp;
                }

            }
        }

        //After sorting
        for(int i=0;i<a.length;i++)
        {
            System.out.print(a[i]+"\t");
        }
        System.out.print("\nAfter removing duplicates:");
        int b=0;
        a[b]=a[0];
        for(int i=0;i<a.length;i++)
        {
            if (a[b]!=a[i])
            {
                b++;
                a[b]=a[i];
            }
        }
        for (int i=0;i<=b;i++ )
        {
            System.out.print(a[i]+"\t");
        }
    }
}
  OUTPUT:Before Sortng:3 2 1 4 2 1 After Sorting:1 1 2 2 3 4 
                Removing Duplicates:1 2 3 4

答案 5 :(得分:5)

这个问题存在很多解决方案。

  1. 排序方法

    • 您对数组进行排序并仅解析唯一项
  2. 设定方法

    • 您声明了一个HashSet,其中您放置了所有项目,然后您只有唯一的项目。
  3. 您创建一个布尔数组,表示所有准备好的项目(这取决于您在数组中的数据)。

  4. 如果您处理大量数据,我会选择1.解决方案。由于您没有分配额外的内存,因此排序速度非常快。对于小的数据集,复杂度将是n ^ 2但是对于大的i,将是n log n。

答案 6 :(得分:4)

如果你创建了两个布尔数组怎么办:1表示负值,1表示正值,并将它们全部设为false。

然后你循环输入数组并在数组中查找已经存在的值。 如果没有,则将其添加到输出数组并将其标记为已使用。

答案 7 :(得分:2)

public static int[] removeDuplicates(int[] arr){
    HashSet<Integer> set = new HashSet<>();
    final int len = arr.length;
    //changed end to len
    for(int i = 0; i < len; i++){
        set.add(arr[i]);
    }

    int[] whitelist = new int[set.size()];
    int i = 0;
    for (Iterator<Integer> it = set.iterator(); it.hasNext();) {
        whitelist[i++] = it.next();
    }
    return whitelist;
}

以O(N)时间而不是O(N ^ 3)时间运行

答案 8 :(得分:2)

由于这个问题仍然受到很多关注,我决定通过复制this answer from Code Review.SE来回答这个问题:

  

您遵循与冒泡排序相同的理念,即   非常非常非常慢你试过这个吗?:

     
      
  • 使用quicksort对无序数组进行排序。 Quicksort要快得多   冒泡排序(我知道,你不是排序,而是算法你   follow几乎与冒泡排序一样遍历数组)。

  •   
  • 然后开始删除重复项(重复的值将在每个旁边   其他)。在for循环中,您可以有两个索引:source和   destination。 (在每个循环中,您将source复制到destination,除非它们   是相同的,并且增加1)。每次你找到一个   重复你增加源(并且不要执行复制)。   @morgano

  •   

答案 9 :(得分:2)

package com.pari.practice;

import java.util.HashSet;
import java.util.Iterator;

import com.pari.sort.Sort;

public class RemoveDuplicates {

 /**
 * brute force- o(N square)
 * 
 * @param input
 * @return
 */
public static int[] removeDups(int[] input){
    boolean[] isSame = new boolean[input.length];
    int sameNums = 0;

    for( int i = 0; i < input.length; i++ ){
        for( int j = i+1; j < input.length; j++){
            if( input[j] == input[i] ){ //compare same
                isSame[j] = true;
                sameNums++;
            }
        }
    }

    //compact the array into the result.
    int[] result = new int[input.length-sameNums];
    int count = 0;
    for( int i = 0; i < input.length; i++ ){
        if( isSame[i] == true) {
            continue;
        }
        else{
            result[count] = input[i];
            count++;
        }
    }

    return result;
}

/**
 * set - o(N)
 * does not guarantee order of elements returned - set property
 * 
 * @param input
 * @return
 */
public static int[] removeDups1(int[] input){
    HashSet myset = new HashSet();

    for( int i = 0; i < input.length; i++ ){
        myset.add(input[i]);
    }

    //compact the array into the result.
    int[] result = new int[myset.size()];
    Iterator setitr = myset.iterator();
    int count = 0;
    while( setitr.hasNext() ){
        result[count] = (int) setitr.next();
        count++;
    }

return result;
}

/**
 * quicksort - o(Nlogn)
 * 
 * @param input
 * @return
 */
public static int[] removeDups2(int[] input){
    Sort st = new Sort();
    st.quickSort(input, 0, input.length-1); //input is sorted

    //compact the array into the result.
    int[] intermediateResult = new int[input.length];
    int count = 0;
    int prev = Integer.MIN_VALUE;
    for( int i = 0; i < input.length; i++ ){
        if( input[i] != prev ){
            intermediateResult[count] = input[i];
            count++;
        }
        prev = input[i];
    }

    int[] result = new int[count];
    System.arraycopy(intermediateResult, 0, result, 0, count);

    return result;
}


public static void printArray(int[] input){
    for( int i = 0; i < input.length; i++ ){
        System.out.print(input[i] + " ");
    }
}

public static void main(String[] args){
    int[] input = {5,6,8,0,1,2,5,9,11,0};
    RemoveDuplicates.printArray(RemoveDuplicates.removeDups(input));
    System.out.println();
    RemoveDuplicates.printArray(RemoveDuplicates.removeDups1(input));
    System.out.println();
    RemoveDuplicates.printArray(RemoveDuplicates.removeDups2(input));
}
}

输出: 5 6 8 0 1 2 9 11

0 1 2 5 6 8 9 11

0 1 2 5 6 8 9 11

我刚刚编写了上面的代码以供尝试。感谢。

答案 10 :(得分:2)

这是对数组中元素进行排序的简单方法

public class DublicatesRemove {
    public static void main(String args[]) throws Exception {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("enter size of the array");
        int l = Integer.parseInt(br.readLine());
        int[] a = new int[l];
        // insert elements in the array logic
        for (int i = 0; i < l; i++) 
        {
            System.out.println("enter a element");
            int el = Integer.parseInt(br.readLine());
            a[i] = el;
        }
        // sorting elements in the array logic
        for (int i = 0; i < l; i++) 
        {
            for (int j = 0; j < l - 1; j++) 
            {
                if (a[j] > a[j + 1])
                {
                    int temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                }
            }
        }
        // remove duplicate elements logic
        int b = 0;
        a[b] = a[0];
        for (int i = 1; i < l; i++)
        {
            if (a[b] != a[i])
            {
                b++;
                a[b]=a[i];

            }

        }
        for(int i=0;i<=b;i++)
        {
            System.out.println(a[i]);
        }


    }
}

答案 11 :(得分:1)

int tempvar=0; //Variable for the final array without any duplicates
     int whilecount=0;    //variable for while loop
     while(whilecount<(nsprtable*2)-1) //nsprtable can be any number
     {
//to check whether the next value is idential in case of sorted array       
if(temparray[whilecount]!=temparray[whilecount+1])
        {
            finalarray[tempvar]=temparray[whilecount];
            tempvar++;
            whilecount=whilecount+1;
        }
        else if (temparray[whilecount]==temparray[whilecount+1])
        {
            finalarray[tempvar]=temparray[whilecount];
            tempvar++;
            whilecount=whilecount+2;
        }
     }

希望这有助于或解决目的。

答案 12 :(得分:1)

public static void main(String args[]) {
    int[] intarray = {1,2,3,4,5,1,2,3,4,5,1,2,3,4,5};

    Set<Integer> set = new HashSet<Integer>();
    for(int i : intarray) {
        set.add(i);
    }

    Iterator<Integer> setitr = set.iterator();
    for(int pos=0; pos < intarray.length; pos ++) {
        if(pos < set.size()) {
            intarray[pos] =setitr.next();
        } else {
            intarray[pos]= 0;
        }
    }

    for(int i: intarray)
    System.out.println(i);
}

答案 13 :(得分:1)

对于已排序的数组,只需检查下一个索引:

//sorted data!
public static int[] distinct(int[] arr) {
    int[] temp = new int[arr.length];

    int count = 0;
    for (int i = 0; i < arr.length; i++) {
        int current = arr[i];

        if(count > 0 )
            if(temp[count - 1] == current)
                continue;

        temp[count] = current;
        count++;
    }

    int[] whitelist = new int[count];
    System.arraycopy(temp, 0, whitelist, 0, count);

    return whitelist;
}

答案 14 :(得分:1)

我知道这有点死了,但我只是写了这个用于我自己的用途。它或多或少与添加到hashset然后从中拉出所有元素相同。它应该在O(nlogn)最坏的情况下运行。

    public static int[] removeDuplicates(int[] numbers) {
    Entry[] entries = new Entry[numbers.length];
    int size = 0;
    for (int i = 0 ; i < numbers.length ; i++) {
        int nextVal = numbers[i];
        int index = nextVal % entries.length;
        Entry e = entries[index];
        if (e == null) {
            entries[index] = new Entry(nextVal);
            size++;
        } else {
            if(e.insert(nextVal)) {
                size++;
            }
        }
    }
    int[] result = new int[size];
    int index = 0;
    for (int i = 0 ; i < entries.length ; i++) {
        Entry current = entries[i];
        while (current != null) {
            result[i++] = current.value;
            current = current.next;
        }
    }
    return result;
}

public static class Entry {
    int value;
    Entry next;

    Entry(int value) {
        this.value = value;
    }

    public boolean insert(int newVal) {
        Entry current = this;
        Entry prev = null;
        while (current != null) {
            if (current.value == newVal) {
                return false;
            } else if(current.next != null) {
                prev = current;
                current = next;
            }
        }
        prev.next = new Entry(value);
        return true;
    }
}

答案 15 :(得分:1)

您需要对数组进行排序,然后循环并删除重复项。由于您无法使用其他工具,因此您需要自己编写代码。

您可以在Java on the internet中轻松找到快速排序的示例(此示例基于此示例)。

public static void main(String[] args) throws Exception {
    final int[] original = new int[]{1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1};
    System.out.println(Arrays.toString(original));
    quicksort(original);
    System.out.println(Arrays.toString(original));
    final int[] unqiue = new int[original.length];
    int prev = original[0];
    unqiue[0] = prev;
    int count = 1;
    for (int i = 1; i < original.length; ++i) {
        if (original[i] != prev) {
            unqiue[count++] = original[i];
        }
        prev = original[i];
    }
    System.out.println(Arrays.toString(unqiue));
    final int[] compressed = new int[count];
    System.arraycopy(unqiue, 0, compressed, 0, count);
    System.out.println(Arrays.toString(compressed));
}

private static void quicksort(final int[] values) {
    if (values.length == 0) {
        return;
    }
    quicksort(values, 0, values.length - 1);
}

private static void quicksort(final int[] values, final int low, final int high) {
    int i = low, j = high;
    int pivot = values[low + (high - low) / 2];
    while (i <= j) {
        while (values[i] < pivot) {
            i++;
        }
        while (values[j] > pivot) {
            j--;
        }
        if (i <= j) {
            swap(values, i, j);
            i++;
            j--;
        }
    }
    if (low < j) {
        quicksort(values, low, j);
    }
    if (i < high) {
        quicksort(values, i, high);
    }
}

private static void swap(final int[] values, final int i, final int j) {
    final int temp = values[i];
    values[i] = values[j];
    values[j] = temp;
}

因此,该过程分三个步骤进行。

  1. 对数组进行排序 - O(nlgn)
  2. 删除重复项 - O(n)
  3. 压缩阵列 - O(n)
  4. 因此,这会显着改善您的O(n^3)方法。

    输出:

    [1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1]
    [1, 1, 1, 2, 4, 4, 7, 8, 8, 9, 9]
    [1, 2, 4, 7, 8, 9, 0, 0, 0, 0, 0]
    [1, 2, 4, 7, 8, 9]
    

    修改

    OP表明数组中的值并不重要。但我可以假设范围介于0-1000 之间。这是一个经典案例,可以使用O(n)种类。

    我们创建了一个大小为range +1的数组,在本例中为1001。然后,我们遍历数据并递增与数据点对应的每个索引上的值。

    然后我们可以压缩生成的数组,删除未递增的值。这使得值在我们忽略计数时是唯一的。

    public static void main(String[] args) throws Exception {
        final int[] original = new int[]{1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1, 1000, 1000};
        System.out.println(Arrays.toString(original));
        final int[] buckets = new int[1001];
        for (final int i : original) {
            buckets[i]++;
        }
        final int[] unique = new int[original.length];
        int count = 0;
        for (int i = 0; i < buckets.length; ++i) {
            if (buckets[i] > 0) {
                unique[count++] = i;
            }
        }
        final int[] compressed = new int[count];
        System.arraycopy(unique, 0, compressed, 0, count);
        System.out.println(Arrays.toString(compressed));
    }
    

    输出:

    [1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1, 1000, 1000]
    [1, 2, 4, 7, 8, 9, 1000]
    

答案 16 :(得分:1)

更新用户输入并不是很大的乐趣,但是要考虑到您的限制...

public int[] removeDup(int[] nums) {
  Arrays.sort(nums);
  int x = 0;
  for (int i = 0; i < nums.length; i++) {
    if (i == 0 || nums[i] != nums[i - 1]) {
    nums[x++] = nums[i];
    }
  }
  return Arrays.copyOf(nums, x);
}

可以使用任何nlog(n)算法轻松替换数组排序。

答案 17 :(得分:0)

这是我的解决方案。时间复杂度为o(n ^ 2)

{{1}}

答案 18 :(得分:0)

const App = () => (
  <BrowserRouter>
    <Provider store={store}>
      <Switch>
        <Route path="/contribute" component={Contribute} />
        <Route path="/" component={Landing} />
      </Switch>
    </Provider>
  </BrowserRouter>
);

答案 19 :(得分:0)

 package javaa;

public class UniqueElementinAnArray 
{

 public static void main(String[] args) 
 {
    int[] a = {10,10,10,10,10,100};
    int[] output = new int[a.length];
    int count = 0;
    int num = 0;

    //Iterate over an array
    for(int i=0; i<a.length; i++)
    {
        num=a[i];
        boolean flag = check(output,num);
        if(flag==false)
        {
            output[count]=num;
            ++count;
        }

    }

    //print the all the elements from an array except zero's (0)
    for (int i : output) 
    {
        if(i!=0 )
            System.out.print(i+"  ");
    }

}

/***
 * If a next number from an array is already exists in unique array then return true else false
 * @param arr   Unique number array. Initially this array is an empty.
 * @param num   Number to be search in unique array. Whether it is duplicate or unique.
 * @return  true: If a number is already exists in an array else false 
 */
public static boolean check(int[] arr, int num)
{
    boolean flag = false;
    for(int i=0;i<arr.length; i++)
    {
        if(arr[i]==num)
        {
            flag = true;
            break;
        }
    }
    return flag;
}

}

答案 20 :(得分:0)

这是一个访谈问题:从数组中删除重复项。我不会使用任何Set或集合。完整的解决方案是:

git remote | xargs git remote remove

答案 21 :(得分:0)

GetRequestStream()

答案 22 :(得分:0)

这里有一种更简单,更好的方法是使用arraylists:

public static final <T> ArrayList<T> removeDuplicates(ArrayList<T> in){
    ArrayList<T> out = new ArrayList<T>();
    for(T t : in) 
        if(!out.contains(t)) 
            out.add(t);
    return out;
}

答案 23 :(得分:0)

如果允许您使用Java 8流:

Arrays.stream(arr).distinct().toArray();

答案 24 :(得分:0)

在不使用set的情况下从整数数组中删除重复项的最有效方法是,仅创建一个temp数组并迭代原始数组,并检查temp数组中是否存在数字,然后不压入数组,否则放入temp数组并返回temp结果数组。请考虑以下代码片段:

package com.numbers;

import java.util.Arrays;

public class RemoveDuplicates {
    public int[] removeDuplicate(int[] array) {
        int[] tempArray = new int[array.length];
        int j = 0;
        for (int i : array) {
            if (!isExists(tempArray, i)) {
                tempArray[j++] = i;
            }
        }
        return tempArray;
    }

    public static boolean isExists(int[] array, int num) {
        if (array == null)
            return false;
        for (int i : array) {
            if (i == num) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int [] array = { 10, 20, 30, 10, 45, 30 };
        RemoveDuplicates duplicates = new RemoveDuplicates();
        System.out.println("Before removing duplicates : " + Arrays.toString(array));
        int [] newArray = duplicates.removeDuplicate(array);
        System.out.println("After removing duplicates : " + Arrays.toString(newArray));

    }
}

答案 25 :(得分:0)

删除重复项只是一个窍门。

public class RemoveDuplicates {
    public static void main(String[] args) {
        int[] arr = {2,2,2,2,2,5,9, 4,5,6,1,6,6,2,4,7};
        arr = removeDuplicates(arr);    
        print(arr);
    }

    public static int[] removeDuplicates(int [] arr) {
        final int garbage = -2147483648;
        int duplicates = 0;

        for(int i=0; i<arr.length; i++) {
            for(int j=i+1; j<arr.length; j++) {
                if (arr[i] == arr[j]) {
                    arr[i] = garbage;
                    duplicates++;
                }
            }
        }

        int[] nArr = new int[arr.length - duplicates];
        int nItr = 0;
        for(int i=0; i<arr.length; i++) {
            if (arr[i] != garbage) {
                nArr[nItr] = arr[i];
                nItr++;
            } 
        }
        return nArr;
    }

    public static void print(int [] arr) {
        for (int n : arr) {
            System.out.print(n + "\t");
        }
    }

}

答案 26 :(得分:0)

public class FindDuplicates {

public static void main(String[] args) 
{
    int a[]={80,70,50,50,30,10,20,10};
    System.out.print("Before Sorting: ");
    for (int i=0;i<a.length; i++ )
    {
        System.out.print(a[i]+"\t");
    }
    System.out.print ("\nAfter Sorting:  ");
    //sorting the elements
    for(int i=0;i<a.length;i++)
    {
        for(int j=i+1;j<a.length;j++)
        {
            if(a[i]>a[j])
            {
                int temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }

        }
    }

    //After sorting
    for(int i=0;i<a.length;i++)
    {
        System.out.print(a[i]+"\t");
    }
    System.out.print("\nAfter removing duplicates:");

    int temp[] = new int[a.length];
    int j=0;
    for (int i=0;i<a.length-1;i++)
    {
        if(a[i]!=a[i+1])
        {
            temp[j]=a[i];
            j++;
        }
    }
    temp[j]=a[a.length-1];
    for (int i=0;i<temp.length;i++)
    {
        System.out.print(temp[i]+"\t");
    }
}
}

答案 27 :(得分:0)

import java.util.Arrays;

public class Practice {

public static void main(String[] args) {
    int a[] = { 1, 3, 3, 4, 2, 1, 5, 6, 7, 7, 8, 10 };
    Arrays.sort(a);
    int j = 0;
    for (int i = 0; i < a.length - 1; i++) {
        if (a[i] != a[i + 1]) {
            a[j] = a[i];
            j++;
        }
    }
    a[j] = a[a.length - 1];
    for (int i = 0; i <= j; i++) {
        System.out.println(a[i]);
    }

}
}
**This is the most simplest way**

答案 28 :(得分:0)

您可以使用辅助数组(temp),该数组在索引中是主数组的编号。因此,时间复杂度将为线性和O(n)。因为我们想在不使用任何库的情况下做到这一点,所以我们定义了另一个数组(唯一)来推送非重复元素:

var num = [2,4,9,4,1,2,24,12,4];
let temp = [];
let unique = [];
let j = 0;
for (let i = 0; i < num.length; i++){
  if (temp[num[i]] !== 1){
    temp[num[i]] = 1;
    unique[j++] = num[i];
  }
}
console.log(unique);

答案 29 :(得分:0)

如果您要使用相同的数组删除重复项,同时还要保持O(n)的时间复杂度。然后,这应该可以解决问题。另外,只有在对数组排序后才能起作用。

function removeDuplicates_sorted(arr){

let j = 0; 

for(let x = 0; x < arr.length - 1; x++){
    
    if(arr[x] != arr[x + 1]){ 
        arr[j++] = arr[x];
    }
}

arr[j++] = arr[arr.length - 1];
arr.length = j;

return arr;

}

这里是未排序数组的O(n),但使用的空间比已排序数组还要复杂。

function removeDuplicates_unsorted(arr){

let map = {};
let j = 0;

for(var numbers of arr){
    if(!map[numbers]){
        map[numbers] = 1;
        arr[j++] = numbers;
    }
}

arr.length = j;

return arr;

}

答案 30 :(得分:0)

我们可以使用堆数据结构删除重复项。

  1. 创建最小堆或最大堆[我使用最小堆](需要O(n)
  2. 从堆中删除元素,如果该元素不在该列表中,则将其存储到另一个列表中。这需要O(nlog(n)),因为我们要从堆中删除一个元素,而要花费log n,我们要这样做直到从堆n * logn中删除所有n个元素为止。

总时间复杂度为O(nlog(n))

我的方法的Python代码

import heapq

l =[1,2,4,6,3,2,6,1]

heapq.heapify(l)
no_duplicate_list =[]

try:
    while True:
        e = heapq.heappop(l)# will return the minimum value from the heap 
        if no_duplicate_list ==[]:
            no_duplicate_list.append(e)
        else:
            if e == no_duplicate_list[-1]:
                continue
            no_duplicate_list.append(e)
except IndexError as i:
    print(no_duplicate_list) #[1, 2, 3, 4, 6]

答案 31 :(得分:0)

为什么所有人都不检查下面的行?

我需要编写自己的实现 - 不要使用Set,HashSet等。或者任何其他工具,如迭代器。只需一个数组即可删除重复项。

我发布了非常简单的实施方案,并注意上述内容。

public class RemoveDuplicates {

public static void main(String[] args) {

    int[] arr = { 1, 2, 3, 4, 2, 3, 1 }; // input array
    int len = arr.length;
    for (int i = 0; i < arr.length; i++) {
        for (int j = i + 1; j < len; j++) {
            if (arr[i] == arr[j]) {
                while (j < (len) - 1) {
                    arr[j] = arr[j - 1];
                    j++;
                }
                len--;
            }
        }
    }
    for (int i = 0; i < len; i++) {
        System.out.print("  " +arr[i]);
    }

   }
 }
  

输入:1,2,3,4,2,3,1

     

输出:1 2 3 4

答案 32 :(得分:0)

好的,所以你不能使用Set或其他收藏品。到目前为止我没有看到的一个解决方案是基于Bloom filter的使用,它本质上是一个位数组,所以可能会超出你的要求。

布隆过滤器是一种可爱且非常方便的技术,快速且节省空间,可用于快速检查集合中元素的存在,而无需存储集合本身或元素。它具有(通常较小的)假阳性率,但没有假阴性率。换句话说,对于您的问题,如果Bloom过滤器告诉您到目前为止尚未看到某个元素,您可以确定它没有。但如果它说已经看到一个元素,你实际上需要检查。如果您的列表中没有太多重复项,这仍然可以节省大量时间(对于那些,没有循环要做,除了在假阳性的小概率情况下 - 您通常根据多少选择此速率您愿意为Bloom过滤器提供的空间(经验法则:每个独特元素少于10位,误报率为1%)。

Bloom过滤器有很多实现,例如, herehere,所以我不会在这个答案中重复这一点。让我们假设最后一个引用中描述的api,特别是put(E e)的{​​{3}}:

  

true如果Bloom过滤器的位由于此操作而改变。如果位改变了,那么第一次将对象添加到过滤器时肯定是。如果位未更改,则可能是第一次将对象添加到过滤器。 (...)

使用这种Bloom过滤器的实现将是:

public static int[] removeDuplicates(int[] arr) {
    ArrayList<Integer> out = new ArrayList<>();
    int n = arr.length;
    BloomFilter<Integer> bf = new BloomFilter<>(...);  // decide how many bits and how many hash functions to use (compromise between space and false positive rate)

    for (int e : arr) {
        boolean might_contain = !bf.put(e);
        boolean found = false;
        if (might_contain) {
            // check if false positive
            for (int u : out) {
                if (u == e) {
                    found = true;
                    break;
                }
            }
        }
        if (!found) {
            out.add(e);
        }
    }
    return out.stream().mapToInt(i -> i).toArray();
}

显然,如果您可以更改传入的数组,那么就不需要ArrayList:最后,当您知道唯一元素的实际数量时,只需要arraycopy()

答案 33 :(得分:0)

这一个怎么样,只有对于排序数组的数字,打印没有重复的数组,不使用Set 或其他集合,只是数组:

 public static int[] removeDuplicates(int[] array) {
    int[] nums =new int[array.length];
    int addedNum = 0;
    int j=0;
    for(int i=0;i<array.length;i++) {
        if (addedNum != array[i]) {
        nums[j] = array[i];
        j++;
        addedNum = nums[j-1];
        }
    }
    return Arrays.copyOf(nums, j);
}

以33020纳秒( 0.033020毫秒)处理的1040个重复数字的数组。

答案 34 :(得分:0)

这不是使用Set,Map,List或任何额外的集合,只有两个数组:

package arrays.duplicates;

import java.lang.reflect.Array;
import java.util.Arrays;

public class ArrayDuplicatesRemover<T> {

    public static <T> T[] removeDuplicates(T[] input, Class<T> clazz) {
        T[] output = (T[]) Array.newInstance(clazz, 0);
        for (T t : input) {
            if (!inArray(t, output)) {
                output = Arrays.copyOf(output, output.length + 1);
                output[output.length - 1] = t;
            }
        }
        return output;
    }

    private static <T> boolean inArray(T search, T[] array) {
        for (T element : array) {
            if (element.equals(search)) {
                return true;
            }
        }
        return false;
    }

}

主要测试它

package arrays.duplicates;

import java.util.Arrays;

public class TestArrayDuplicates {

    public static void main(String[] args) {
        Integer[] array = {1, 1, 2, 2, 3, 3, 3, 3, 4};
        testArrayDuplicatesRemover(array);
    }

    private static void testArrayDuplicatesRemover(Integer[] array) {
        final Integer[] expectedResult = {1, 2, 3, 4};
        Integer[] arrayWithoutDuplicates = ArrayDuplicatesRemover.removeDuplicates(array, Integer.class);
        System.out.println("Array without duplicates is supposed to be: " + Arrays.toString(expectedResult));
        System.out.println("Array without duplicates currently is: " + Arrays.toString(arrayWithoutDuplicates));
        System.out.println("Is test passed ok?: " + (Arrays.equals(arrayWithoutDuplicates, expectedResult) ? "YES" : "NO"));
    }

}

输出:

Array without duplicates is supposed to be: [1, 2, 3, 4]
Array without duplicates currently is: [1, 2, 3, 4]
Is test passed ok?: YES

答案 35 :(得分:0)

我觉得Android Killer的想法很棒,但我只是想知道我们是否可以利用HashMap。所以我做了一个小实验。我发现HashMap似乎比HashSet更快。

这是代码:

    int[] input = new int[1000000];

    for (int i = 0; i < input.length; i++) {
        Random random = new Random();
        input[i] = random.nextInt(200000);
    }

    long startTime1 = new Date().getTime();
    System.out.println("Set start time:" + startTime1);

    Set<Integer> resultSet = new HashSet<Integer>();

    for (int i = 0; i < input.length; i++) {
        resultSet.add(input[i]);
    }

    long endTime1 = new Date().getTime();
    System.out.println("Set end time:"+ endTime1);
    System.out.println("result of set:" + (endTime1 - startTime1));     
    System.out.println("number of Set:" + resultSet.size() + "\n");

    long startTime2 = new Date().getTime();
    System.out.println("Map start time:" + startTime1);

    Map<Integer, Integer> resultMap = new HashMap<Integer, Integer>();

    for (int i = 0; i < input.length; i++) {
        if (!resultMap.containsKey(input[i]))
            resultMap.put(input[i], input[i]);
    }

    long endTime2 = new Date().getTime();
    System.out.println("Map end Time:" + endTime2);
    System.out.println("result of Map:" + (endTime2 - startTime2));
    System.out.println("number of Map:" + resultMap.size());

结果如下:

Set start time:1441960583837
Set end time:1441960583917
result of set:80
number of Set:198652

Map start time:1441960583837
Map end Time:1441960583983
result of Map:66
number of Map:198652

答案 36 :(得分:-1)

请检查一下。它适用于已排序/未排序的数组。复杂度为O(n ^ 2)与冒泡排序相同。 是的,通过第一次排序然后二进制搜索可以进一步提高复杂性。但这很简单,可以处理除负元素(-1)之外的所有情况。这也可以通过使用大整数值而不是-1来改变。

void remove_duplicates(int *A, int N)

{

int i,j;

for (i=1; i<N; i++) {
    if (A[i] == -1) continue;
    for (j=i+1; j<=N; j++) {
        if (A[i] == A[j])
            A[j] = -1;
    }
}
}

int main() {

int N;
int A[1001];
int i;

printf("Enter N: ");
scanf("%d", &N);
printf("Enter the elements:\n");
for (i=1; i<=N; i++)
    scanf("%d", &A[i]);

remove_duplicates(A, N);
for (i=1; i<=N; i++) {
    if (A[i] == -1)
        continue;
    printf("%d  ", A[i]);
}
printf("\n");

return 0;
}

答案 37 :(得分:-2)

import java.util.*;
class removeDuplicate{
int [] y ;

public removeDuplicate(int[] array){
    y=array;


    for(int b=0;b<y.length;b++){
        int temp = y[b];
        for(int v=0;v<y.length;v++){
            if( b!=v && temp==y[v]){
                y[v]=0;
            }
        }
    }




}

答案 38 :(得分:-2)

    public static int[] removeDuplicates(int[] input){

        int j = 0;
        int i = 1;
        //return if the array length is less than 2
        if(input.length < 2){
            return input;
        }
        while(i < input.length){
            if(input[i] == input[j]){
                i++;
            }else{
                j = j+1;
                input[j] = input[i];
                i = i+1;
            }    
        }
        int[] output = new int[j+1];
        for(int k=0; k<output.length; k++){
            output[k] = input[k];
        }

        return output;
    }

public static void main(String a[]){
        int[] input1 = {2,3,6,6,8,9,10,10,10,12,12};
        int[] output = removeDuplicates(input1);
        for(int i:output){
            System.out.println(i+" ");
        }
    }

答案 39 :(得分:-2)

第一个答案是使用hashset设计用于删除重复项,因为Android Killer的答案指出

方法2: - 但是,如果您不允许使用set,则先使用快速排序对其进行排序,然后应用XOR操作来查找重复项

优化一个

public static void removeDuplicates(int[] arr) {
        int[] input = new int[] { 1, 1, 3, 7, 7, 8, 9, 9, 9, 10 };
        int current = input[0];
        boolean found = false;

        for (int i = 0; i < input.length-1; i++) {

            if((input[i]^input[i+1])==0){
                System.out.println(input[i]);
            }
        }

    }

答案 40 :(得分:-2)

//Remove duplicate from sorted array

public class RemDupFromArray {
    static int num;
    public static void main(String[] args){
        int arr[] = {0,0,2,2,3, 5, 5,7, 7, 7};
        for(int i=0;i<arr.length-1;i++){
            if(num!=arr[i]){
                num=arr[i];
                System.out.print(arr[i]);
            }
        }
    }
}

答案 41 :(得分:-2)

public class RemoveDuplicates {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int size;
        System.out.println("Enter an array size");
        Scanner sc=new Scanner(System.in);
        size = sc.nextInt();

        int arr[] = new int[size];

        System.out.println("Enter "+size+" numbers");
        for(int i=0;i<size;i++){
            arr[i]=sc.nextInt();
        }

        for(int i=0;i<size;i++){
            int count=0;
            for(int j=i+1;j<size;j++){
                if(arr[i]==arr[j]){

                    int shiftLeft = j;

                    for (int k = j+1; k < size; k++, shiftLeft++) {
                        arr[shiftLeft] = arr[k];
                    }
                    size--;
                    j--;
                }
            }
        }
        System.out.println("New Array");
        for(int i=0;i<size;i++)
        {
            System.out.println(arr[i]);
        }
    }

}

答案 42 :(得分:-2)

希望它有所帮助...

if (!checked)//Condition to add into array {
        $scope.selectWeekDays.push(WeekKeys);
    } else {
        for (i = 0; i <= $scope.selectWeekDays.length; i++) // Loop to check IsExists {
            if ($scope.selectWeekDays[i] == WeekKeys)//then if Equals removing by splice {
                $scope.selectWeekDays.splice(i, 1);
                break;
            }
        }
    }

答案 43 :(得分:-2)

根据需要使用ArrayUtil类。除了删除重复项之外,我还写了一些方法。无需使用任何Collection框架类即可实现此类。

public class ArrayUtils {
/**
 * Removes all duplicate elements from an array. 
 * @param arr Array from which duplicate elements are to be removed.
 * @param removeAllDuplicates true if remove all duplicate values, false otherwise 
 * @return Array of unique elements.
 */
public static int[] removeDuplicate(int[] arr, boolean removeAllDuplicates)         {
    int size = arr.length;

    for (int i = 0; i < size;) {
        boolean flag = false;

        for (int j = i + 1; j < size;) {
            if (arr[i] == arr[j]) {
                flag = true;
                shrinkArray(arr, j, size);
                size--;
            } else
                j++;
        }

        if (flag && removeAllDuplicates) {
            shrinkArray(arr, i, size);
            size--;
        } else
            i++;
    }

    int unique[] = new int[size];
    for (int i = 0; i < size; i++)
        unique[i] = arr[i];

    return unique;
}

/**
 * Removes duplicate elements from an array. 
 * @param arr Array from which duplicate elements are to be removed.
 * @return Array of unique elements.
 */
public static int[] removeDuplicate(int[] arr) {
    return removeDuplicate(arr, false);
}


private static void shrinkArray(int[] arr, int pos, int size) {
    for (int i = pos; i < size - 1; i++) {
        arr[i] = arr[i + 1];
    }
}

/**
 * Displays the array.
 * @param arr The array to be displayed.
 */
public static void displayArray(int arr[]) {
    System.out.println("\n\nThe Array Is:-\n");

    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i] + "\t");
    }
}

/**
 * Initializes the array with a given value.
 * @param arr The array to be initialized.
 * @param withValue The value with which the array is to be initialized.
 */
public static void initializeArray(int[] arr, int withValue) {
    for (int i = 0; i < arr.length; i++) {
        arr[i] = withValue;
    }
}

/**
 * Checks whether an element is there in the array. 
 * @param arr The array in which the element is to be found.
 * @param element The element that is to be found.
 * @return True if found false otherwise
 */
public static boolean contains(int arr[], int element) {
    for(int i=0; i< arr.length; i++) {
        if(arr[i] == element)
            return true;
    }

    return false;
}

/**
 * Removes a element from an array.
 * @param arr The array from which the element is to removed.
 * @param element The element to be removed
 * @return The size of the array after removing.
 */
public static int removeElement(int[] arr, int element) {
    int size = arr.length;
    for(int i=0; i< arr.length; i++){
        if(arr[i] == element){
            shrinkArray(arr, i, arr.length);
            size--;
        }
    }
    return size;
}

/**
 * Counts unique elements in an array.
 * @param arr The required array.
 * @return Unique element count.
 */
public static int uniqueElementCount(int arr[]) {
    int count = 0;
    int uniqueCount=0;
    int[] consideredElements = new int[arr.length];

    initializeArray(consideredElements, 0);

    for(int i=0;i<arr.length;i++) {
        int element = arr[i];
        for(int j=i+1;j<arr.length; j++){
            if(element != arr[j] && !contains(consideredElements, element)){
                consideredElements[count++] = element;
            }
        }
    }

    for(int i=0;i< consideredElements.length;i++)
        if(consideredElements[i]!=0)
            uniqueCount++;

    return uniqueCount;
}
}

答案 44 :(得分:-2)

我已经将样本用作12个元素,

公共课Remdup_arr {

public static void main(String[] args) {

    int a[] = {1,1,2,3,4,4,5,6,7,8,6,8};
    for(int p : a)
    {
        System.out.print(p);
        System.out.print("\t");
    }

    System.out.println();
    System.out.println();

    remdup(a);

}

private static void remdup(int[] a) {

    int length = a.length;
    int b[] = new int[11];
    int d = 1;
    b[0]=a[0];
    while(length<13 && length>0)
    {
        int x = a[length-1];
        if(!(contain(b , x)))
            {b[d] = a[length-1];
            d++;}
        length--;


    }

    for( int z = 0;z<b.length;z++){
        System.out.print(b[z]);
        System.out.print("\t");}

}

private static boolean contain(int[] b ,int p) {

    boolean bool = false;
    int len = b.length;
    for(int i = 0;i<len;i++)
    {
        if(p == b[i])
            bool = true;
    }



    return bool;

}

}

输出是: - 1 1 2 3 4 4 5 6 7 8 6 8

1 8 6 7 5 4 3 2 0 0 0

答案 45 :(得分:-2)

public class RemoveDuplicates {
public Integer[] returnUniqueNumbers(Integer[] original,
        Integer[] uniqueNumbers) {
    int k = 0;  

    for (int j =  original.length - 1; j >= 0; j--) {
        boolean present = false;
        for (Integer u : uniqueNumbers) {
            if (u != null){
            if(u.equals(original[j])) {
                present = true;
            }}
        }
        if (present == false) {
            uniqueNumbers[k] = original[j];
            k++;
        }
    }
    return uniqueNumbers;
}

public static void main(String args[]) {
    RemoveDuplicates removeDup = new RemoveDuplicates();
    Integer[] original = { 10, 20, 40, 30, 50, 40, 30, 20, 10, 50, 50, 50,20,30,10,40 };
    Integer[] finalValue = new Integer[original.length + 1];

    // method to return unique values
    Integer[] unique = removeDup.returnUniqueNumbers(original, finalValue);

    // iterate to return unique values
    for (Integer u : unique) {
        if (u != null) {
            System.out.println("unique value : " + u);
        }
    }
}}

此代码处理包含多个重复项的未排序数组以获取相同的值,并返回唯一元素。

答案 46 :(得分:-3)

  public static void main(String[] args) { 
            int input[] = { 1, 5, 1, 0, -3, 1, -3, 2, 1 }; 
            int j = 0; 
            int output[] = new int[100]; 
            Arrays.fill(a, 0); 
            for (int i = 0; i < 9; i++) { 
                    if (output[input[i]] == 0) {
                            input[j++] = input[i]; 
                            output[input[i]]++; 
                    } 
            } 
            for (int i = 0; i < j; i++) { 
                    System.out.print(input[i] + " "); 
            } 
    }