Hoe efficiënt duplicaten uit een array te verwijderen zonder Set te gebruiken

Ik werd gevraagd om mijn eigen implementatie te schrijven om dubbele waarden in een array te verwijderen. Hier is wat ik heb gemaakt. Maar na tests met 1.000.000 elementen duurde het erg lang voordat het klaar was. Kan ik iets doen om mijn algoritme te verbeteren of bugs te verwijderen?

Ik moet mijn eigen implementatie schrijven – niet om Set, HashSetenz. Of andere tools zoals iterators. Gewoon een array om duplicaten te verwijderen.

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;
}

Antwoord 1, autoriteit 100%

u kunt de hulp gebruiken van Setcollectie

int end = arr.length;
Set<Integer> set = new HashSet<Integer>();
for(int i = 0; i < end; i++){
  set.add(arr[i]);
}

Als je nu door deze setgaat, zal deze alleen unieke waarden bevatten. Itererende code is als volgt:

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

Antwoord 2, autoriteit 40%

Als u Java 8-streams mag gebruiken:

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

Antwoord 3, autoriteit 37%

Opmerking: ik ga ervan uit dat de array is gesorteerd.

Code:

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);

uitvoer:

 1 3 7 8 9 10

Antwoord 4, autoriteit 26%

Kleine wijziging van de originele code zelf, door de binnenste for-lus te verwijderen.

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;
}

Antwoord 5, autoriteit 19%

Omdat je kunt aannemen dat het bereik tussen 0-1000 ligt, is er een zeer eenvoudige en efficiënte oplossing

//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;
}

Dit loopt in lineaire tijd O(n). Waarschuwing: de geretourneerde array is gesorteerd, dus als dat illegaal is, is dit antwoord ongeldig.


Antwoord 6, autoriteit 19%

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

Antwoord 7, autoriteit 16%

Er zijn veel oplossingen voor dit probleem.

  1. De sorteerbenadering

    • U sorteert uw array en lost alleen unieke items op
  2. De vaste aanpak

    • Je declareert een HashSet waar je alle items plaatst, dan heb je alleen unieke items.
  3. U maakt een booleaanse array die de items representeert die allemaal klaar zijn geretourneerd (dit hangt af van uw gegevens in de array).

Als je te maken hebt met grote hoeveelheden data, zou ik de 1. oplossing kiezen. Omdat je geen extra geheugen toewijst en het sorteren vrij snel gaat. Voor een kleine set gegevens zou de complexiteit n ^ 2 zijn, maar voor grote zal ik n log n zijn.


Antwoord 8, autoriteit 12%

Aangezien deze vraag nog steeds veel aandacht krijgt, heb ik besloten deze te beantwoorden door dit antwoord van Code Review.SE te kopiëren. :

Je volgt dezelfde filosofie als de bellensoort, namelijk:
heel, heel, heel langzaam. Heb je dit geprobeerd?:

  • Sorteer je ongeordende array met quicksort. Quicksort is veel sneller
    dan bellen sorteren (ik weet het, je sorteert niet, maar het algoritme dat je
    volgen is bijna hetzelfde als bellen sorteren om de array te doorkruisen).

  • Begin dan met het verwijderen van duplicaten (herhaalde waarden staan naast elkaar
    ander). In een forlus zou je twee indices kunnen hebben: sourceen
    destination. (Bij elke lus kopieer je sourcenaar destinationtenzij ze
    zijn hetzelfde en verhogen beide met 1). Elke keer dat je een vindt
    dupliceer je bron (en voer de kopie niet uit).
    @morgano


Antwoord 9, autoriteit 9%

Wat als u twee booleaanse arrays maakt: 1 voor negatieve waarden en 1 voor positieve waarden en het allemaal op false start.

Vervolgens blader je door de invoerarray en zoek je in de arrays op als je de waarde al bent tegengekomen.
Als dat niet het geval is, voegt u het toe aan de uitvoerarray en markeert u het als reeds gebruikt.


Antwoord 10, autoriteit 7%

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));
}
}

Uitvoer:
5 6 8 0 1 2 9 11

0 1 2 5 6 8 9 11

0 1 2 5 6 8 9 11

Ik heb zojuist de bovenstaande code geschreven om uit te proberen. bedankt.


Antwoord 11, autoriteit 7%

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;
}

Loopt in O(N)-tijd in plaats van uw O(N^3)-tijd


Antwoord 12, autoriteit 7%

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**

Antwoord 13, autoriteit 5%

Dit is een eenvoudige manier om de elementen in de array te sorteren

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]);
        }
    }
}

Antwoord 14, autoriteit 5%

Voor een gesorteerde array, check gewoon de volgende index:

//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;
}

Antwoord 15, autoriteit 5%

Het is niet erg leuk om gebruikersinvoer bij te werken, maar gezien uw beperkingen…

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);
}

Array sorteren kan eenvoudig worden vervangen door elk nlog(n)-algoritme.


Antwoord 16, autoriteit 2%

U moet uw array sorteren en vervolgens herhalen en duplicaten verwijderen. Omdat je geen andere tools kunt gebruiken, moet je zelf code schrijven.

U kunt eenvoudig voorbeelden van quicksort in Java vinden op internet(op waarop dit voorbeeld is gebaseerd).

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;
}

Dus loopt het proces in 3 stappen.

  1. Sorteer de array – O(nlgn)
  2. Duplicaten verwijderen – O(n)
  3. Compact De array – O(n)

Dus dit verbetert aanzienlijk op uw O(n^3)benadering.

Uitgang:

[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]

bewerken

OP-staten Waarden in de array doet er echt niet toe. Maar ik kan aannemen dat het bereik tussen 0-1000 is. Dit is een klassiek geval waar een o (n) soort sortering kan worden gebruikt.

We maken een reeks grootte range +1, in dit geval 1001. We lijden vervolgens over de gegevens en verhogen de waarden op elke index die overeenkomt met de Datapoint.

We kunnen vervolgens de resulterende array comprimeren, vallen waarden die niet zijn verhoogd. Dit maakt de waarden uniek als we de telling negeren.

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));
}

Uitvoer:

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

Antwoord 17, autoriteit 2%

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);
}

Antwoord 18, autoriteit 2%

Ik weet dat dit een beetje dood is, maar ik heb dit alleen voor eigen gebruik geschreven. Het is min of meer hetzelfde als toevoegen aan een hashset en vervolgens alle elementen eruit halen. Het zou in O(nlogn) in het slechtste geval moeten werken.

   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;
    }
}

19, Autoriteit 2%

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, Autoriteit 2%

U kunt een extra array (TEMP) gebruiken die in indexen aantallen hoofdarray zijn. Dus de tijdcomplexiteit zal voering en o (n) zijn. Zoals we het willen doen zonder gebruik te maken van een bibliotheek, definiëren we een andere array (uniek) om niet-dubbele elementen te duwen:

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);

Antwoord 21, autoriteit 2%

Als u duplicaten wilt verwijderen met dezelfde array en ook de tijdcomplexiteit van O(n) wilt behouden. Dan zou dit het moeten doen. Zou ook alleen werken als de array gesorteerd is.

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;

}

Hier is voor een ongesorteerde array, de O(n) maar gebruikt meer ruimtecomplexiteit dan de gesorteerde.

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;

}


Antwoord 22

public static void main(String[] args) {
        Integer[] intArray = { 1, 1, 1, 2, 4, 2, 3, 5, 3, 6, 7, 3, 4, 5 };
        Integer[] finalArray = removeDuplicates(intArray);
        System.err.println(Arrays.asList(finalArray));
    }
    private static Integer[] removeDuplicates(Integer[] intArray) {
        int count = 0;
        Integer[] interimArray = new Integer[intArray.length];
        for (int i = 0; i < intArray.length; i++) {
            boolean exists = false;
            for (int j = 0; j < interimArray.length; j++) {
                if (interimArray[j]!=null && interimArray[j] == intArray[i]) {
                    exists = true;
                }
            }
            if (!exists) {
                interimArray[count] = intArray[i];
                count++;
            }
        }
        final Integer[] finalArray = new Integer[count];
        System.arraycopy(interimArray, 0, finalArray, 0, count);
        return finalArray;
    }

Antwoord 23

Ik vind het idee van Android Killer geweldig, maar ik vroeg me af of we HashMap kunnen gebruiken. Dus deed ik een klein experiment. En ik ontdekte dat HashMap sneller lijkt dan HashSet.

Hier is de code:

   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());

Hier is het resultaat:

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

Antwoord 24

Dit gebruikt geen Set, Map, List of een extra collectie, maar twee arrays:

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;
    }
}

En de belangrijkste om het te testen

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"));
    }
}

En de uitvoer:

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

Antwoord 25

Wat dacht je van deze, alleen voor gesorteerde arrayvan getallen, om array af te drukken zonder duplicaten, zonder Setof andere verzamelingen te gebruiken, gewoon Array:

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);
}

Array van 1040 gedupliceerde getallen verwerkt in 33020 nanoseconden(0,033020 millisec).


Antwoord 26

Ok, je kunt dus geen Setof andere collecties gebruiken. Een oplossing die ik hier tot nu toe niet zie, is gebaseerd op het gebruik van een Bloom-filter, wat in wezen een reeks bits is, dus misschien voldoet dat aan uw vereisten.

Het bloomfilter is een mooie en zeer handige techniek, snel en ruimte-efficiënt, die kan worden gebruikt om een ​​snelle controle van het bestaan ​​van een element in een set te doen zonder de set zelf of de elementen op te slaan. Het heeft een (typisch klein) vals positief tarief, maar geen vals negatief tarief. Met andere woorden, voor uw vraag, als een bloeifilter u vertelt dat een element tot nu toe nog niet is gezien, kunt u er zeker van zijn dat het dat niet heeft. Maar als het zegt dat een element is gezien, moet u eigenlijk controleren. Dit bespaart nog steeds veel tijd als er niet te veel duplicaten in je lijst zijn (voor die, er is geen looping om te doen, behalve in het kleine waarschijnlijkheidsgevoel van een vals-positief – Jeestal koos dit tarief op basis van hoeveel Ruimte die u bereid bent te geven aan het bloeifilter (vuistregel: minder dan 10 bits per uniek element voor een valse positieve snelheid van 1%).

Er zijn veel implementaties van bloomfilters, zie b.v. hier of Hier , dus ik zal dat niet herhalen in dit antwoord. Laten we gewoon aannemen dat de API beschreven in die laatste referentie, in het bijzonder, de Beschrijving van put(E e):

trueAls de bits van de bloeipilter veranderden als gevolg van deze bewerking. Als de bits gewijzigd, is dit absoluut het eerste keer dat het voorwerp is toegevoegd aan het filter. Als de bits niet zijn gewijzigd, kan dit het eerste keer dat het object is toegevoegd aan het filter. (…)

Een implementatie met behulp van een dergelijk bloeifilter zou dan zijn:

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();
}

Het is duidelijk dat als u de inkomende array op zijn plaats kunt wijzigen, er geen ArrayListnodig is: aan het einde, als u het werkelijke aantal unieke elementen weet, hoeft u alleen maar arraycopy()die.


Antwoord 27

Waarom controleren niet alle mensen dit onder de regels?

Ik moet mijn eigen implementatie schrijven – niet om Set, HashSet etc. of andere tools zoals iterators te gebruiken. Gewoon een array om duplicaten te verwijderen.

Ik plaats een heel eenvoudige implementatie met zorg voor de bovenstaande regel.

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]);
    }
   }
 }

Invoer: 1, 2, 3, 4, 2, 3, 1

Uitvoer: 1 2 3 4


Antwoord 28

Hier is mijn oplossing. De tijdscomplexiteit is o(n^2)

public String removeDuplicates(char[] arr) {
        StringBuilder sb = new StringBuilder();
        if (arr == null)
            return null;
        int len = arr.length;
        if (arr.length < 2)
            return sb.append(arr[0]).toString();
        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j < len; j++) {
                if (arr[i] == arr[j]) {
                    arr[j] = 0;
                }
            }
            if (arr[i] != 0)
                sb.append(arr[i]);
        }
        return sb.toString().trim();
    }

Antwoord 29

public void removeDup(){ 
String[] arr = {"1","1","2","3","3"};
          boolean exists = false;
          String[] arr2 = new String[arr.length];
          int count1 = 0;
          for(int loop=0;loop<arr.length;loop++)
            {
              String val = arr[loop];
              exists = false;
              for(int loop2=0;loop2<arr2.length;loop2++)
              {     
                  if(arr2[loop2]==null)break;
                  if(arr2[loop2]==val){
                        exists = true;
                }
              }
              if(!exists) {
                    arr2[count1] = val;
                    count1++;
              }
            }
}

Other episodes