Façon la plus efficace de supprimer les doublons d'un tableau sans l'aide de Jeu
M'a demandé d'écrire mon propre mise en œuvre pour supprimer les doublons dans un tableau. Voici ce que j'ai créé. Mais après des tests avec 1 000 000 d'éléments qu'il a pris beaucoup de temps pour terminer. Il y a une chose que je peux faire pour améliorer mon algorithme ou un bug à supprimer ?
J'ai besoin d'écrire ma propre mise en œuvre - ne pas utiliser Set
, HashSet
etc. Ou tout autres outils tels que les itérateurs. Tout simplement un tableau de supprimer les doublons.
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;
}
- Quelles sont les restrictions placées sur vous? Pouvez-vous
sort
? Vous pouvez certainement améliorer cette O(n^3) la mise en œuvre. Cet algorithme doit être O(nln(n)) dans le meilleur des cas. - Eh bien oui, vous avez un O(n^3) algorithme... qui ne sonne pas comme une bonne idée pour moi.
- vous pouvez utiliser
Set<Integer>
? - Vous avez demandé ce dans Codereview, trop. Il y a réponse, trop.
- Oui, le tableau peut être trié.
- On m'a demandé d'écrire mon propre mise en œuvre, de ne pas utiliser d'outils.
- J'ai demandé, mais il n'y a pas trop d'attention, donc je demande ici.
- Peut-être jeter un oeil à la réponse. Il va vous aider.
- Quelle est la portée de la
int
s dans les tableaux? Si elle est connue et petit, vous pouvez faire un seau de tri et supprimer les doublons que vous allez. - des valeurs à l'intérieur de la matrice de n'importe pas vraiment. Mais je peux supposer que la fourchette est entre 0-1000.
- Eh bien, vous avez déjà deux réponses dans le la revue de code forum
- double possible de Java Supprimer les Doublons d'un Tableau?
- Cette question semble être hors-sujet parce que c'est de demander une révision du code. Voir Quels sont les sujets que pouvez-vous nous parler ici dans le Centre d'Aide. Peut-être l'Examen du Code de la Pile d'Échange serait un meilleur endroit pour demander cela.
- double possible de Comment puis-je supprimer les éléments répétés de ArrayList?
- Double Possible de Algorithm: moyen efficace pour supprimer les doubles des nombres entiers à partir d'un tableau
- code peuvent bénéficier de trier le tableau et ensuite utiliser cette information pour modifier le tableau en place et d'obtenir un nouvel indice.
Vous devez vous connecter pour publier un commentaire.
vous pouvez prendre l'aide de Ensemble collection
maintenant, si vous voulez parcourir cette ensemble, il ne contiendra que des valeurs uniques. L'itération du code ressemble à ceci :
Note: je suis en supposant que le tableau est trié.
Code:
de sortie:
Légère modification au code original lui-même, en supprimant les recoins les plus profonds de la boucle.
Puisque vous pouvez assumer la gamme est entre 0-1000 il y a une solution très simple et efficace
Cela s'exécute en temps linéaire O(n). Mise en garde: le tableau retourné est trié donc, si c'est illégal alors cette réponse n'est pas valide.
== false
et== true
? Jamais entendu parler de!
?Il existe de nombreuses solution de ce problème.
Le tri approche
L'approche
Vous créer un booléen tableau qui représentent les éléments de tous les prêts retourné, (cela dépend de vos données dans le tableau).
Si vous faites affaire avec une grande quantité de données, je choisirais le 1. solution. Comme vous n'avez pas à allouer de la mémoire supplémentaire et que le tri est assez rapide. Pour petit ensemble de données de la complexité serait n^2, mais pour les grands, je n log n.
Que si vous créez deux booléens tableaux: 1 pour les valeurs négatives et 1 pour les valeurs positives et init tout faux.
Alors vous cycle thorugh le tableau d'entrée et de recherche dans les tableaux si vous avez rencontré la valeur déjà.
Si non, vous l'ajouter au tableau de sortie et le marquer comme étant déjà utilisé.
C'est simple pour trier les éléments dans le tableau
De sortie:
5 6 8 0 1 2 9 11
0 1 2 5 6 8 9 11
0 1 2 5 6 8 9 11
Je viens d'écrire le code ci-dessus pour essayer. merci.
Depuis que cette question est encore l'objet de beaucoup d'attention, j'ai décidé de répondre par la copie cette réponse de la Révision du Code.SE:
S'exécute en O(N) fois au lieu de votre O(N^3) temps
Vous avez besoin de trier votre tableau puis ensuite en boucle et supprimer les doublons. Comme vous ne pouvez pas utiliser d'autres outils que vous devez écrire le code sera vous-même.
Vous pouvez facilement trouver des exemples de quicksort en Java sur internet (sur lequel cet exemple est basé).
De sorte que le processus s'exécute en 3 étapes.
O(nlgn)
O(n)
O(n)
Donc, ce qui améliore de manière significative sur votre
O(n^3)
approche.De sortie:
MODIFIER
OP états des valeurs à l'intérieur de la matrice de n'importe pas vraiment. Mais je peux supposer que la fourchette est entre 0-1000. C'est un cas classique où un O(n) peut être utilisé.
Nous créons un tableau de taille
range +1
, dans ce cas1001
. Nous avons ensuite une boucle sur les données et incrémenter les valeurs de chaque indice correspondant à la datapoint.Nous pouvons alors compact le tableau qui en résulte, à l'abandon des valeurs de la n'ont pas été incrémenté. Cela rend les valeurs uniques que nous ignorons le nombre de.
De sortie:
Je sais que c'est un peu mort, mais je viens d'écrire pour mon propre usage. C'est plus ou moins le même que l'ajout d'un hashset, puis en tirant tous les éléments en dehors de ça. Il doit s'exécuter en O(nlogn) le pire des cas.
Espère que cette aide ou résout le but.
Pour un Tableau trié, il suffit de voir le prochain indice:
new int[] {};
est un tableau vide, de sorte que vous obtiendrez unArrayIndexOutOfBoundsException
. Plus de la construction de barrages est peut-être que binaire de recherche ne fonctionne que sur données triées. Vous n'avez pas trié les données. Et une fois que les données sont triées puis le binaire de recherche est redondante.int[]
ànew int[arr.lenght]
sinon le code ne fonctionne pas. Et vous avez besoin d'ajouter que le tableau doit être déjà triés. Toutes les OP dit c'est que vous peut trier les données non pas qu'il est déjà triée. Je ne pense toujours pas que cette réponse est correcte. Et comme pour le tri == unqiue, ce n'est pas ce que j'ai dit. Tout ce que je dit c'est que si les données sont triées puis vous pouvez trouver les valeurs uniques sans binaire de recherche telles qu'elles sont, par définition, adjacente par conséquent, vous n'avez pas besoin d'aller chercher pour eux.Pas un grand plaisir de la mise à jour de la saisie de l'utilisateur, cependant, compte tenu de vos contraintes...
Tableau de tri peut être facilement remplacé par un autre nlog(n) de l'algorithme.
Je ressens Android Killer idée est excellente, mais je me demandais si nous pouvons tirer parti de table de hachage. J'ai donc fait une petite expérience. Et j'ai trouvé HashMap semble plus rapide que HashSet.
Voici le code:
Voici le résultat:
Ce n'est pas à l'aide de Jeu, Carte, Liste ou de toute collecte supplémentaire, seulement deux tableaux:
Et la main pour le tester
Et la sortie:
Comment à ce sujet, seul pour tableau trié de nombres, de l'imprimer, de matrice, sans doublons, sans l'aide de Jeu de ou d'autres Collections, juste de Tableau:
Tableau de 1040 dupliqué numéros traitées dans 33020 nanosecondes(0.033020 millisec).
D'accord, alors vous ne pouvez pas utiliser
Set
ou d'autres collections. Une seule solution, je ne vois pas ici la mesure est basé sur l'utilisation d'un Filtre de Bloom, qui est essentiellement un tableau de bits, donc peut-être qui répond à vos exigences.Le filtre de Bloom est une belle et très pratique technique, rapide et efficace, qui peut être utilisé pour faire une vérification rapide de l'existence d'un élément dans un ensemble sans stocker l'ensemble lui-même ou les éléments. Il a un (généralement de petite taille) taux de faux positifs, mais pas de taux de faux négatifs. En d'autres termes, pour votre question, si un filtre de Bloom vous dit qu'un élément n'a pas été vu jusqu'à présent, vous pouvez être sûr qu'il n'a pas. Mais si on dit qu'un élément a été vu, vous avez vraiment besoin de vérifier. Encore permet d'économiser beaucoup de temps si il n'y a pas trop de doublons dans votre liste (pour ceux-ci, il n'y a pas de boucle à faire, sauf dans les petits probabilité cas de faux positif-vous généralement choisi ce taux en fonction de la quantité d'espace que vous êtes prêt à donner à la Floraison de filtre (règle de base: moins de 10 bits par élément unique pour un taux de faux positif de 1%).
Il existe de nombreuses implémentations de filtres de Bloom, voir, par exemple, ici ou ici, donc je ne vais pas répéter ce que, dans cette réponse. Contentons-nous d'assumer l'api décrite dans cette dernière référence, en particulier, la description de
put(E e)
:Une mise en œuvre en utilisant par exemple un filtre de Bloom serait alors:
Évidemment, si vous pouvez modifier les entrants réseau en place, il n'est pas nécessaire pour une
ArrayList
: à la fin, quand tu sais le nombre réel d'éléments uniques, justearraycopy()
ceux.Pourquoi tous les gens de ne pas cocher cette ci-dessous les lignes?
J'ai besoin d'écrire ma propre mise en œuvre - ne pas utiliser d'Ensemble, HashSet, etc. Ou tout autres outils tels que les itérateurs. Tout simplement un tableau de supprimer les doublons.
Je poste très simple de mise en œuvre avec soin la ligne ci-dessus.
Voici ma solution. Le temps de la complexité est o(n^2)
}
C'est une question d'entrevue :Supprimer les doublons d'un tableau.Je ne doit pas utiliser n'importe quel Ensemble ou collections. La solution complète est :
Heres un plus simple, meilleure façon de le faire à l'aide de arraylists à la place:
Si vous êtes autorisé à utiliser Java 8 flux:
Le moyen le plus efficace pour supprimer les doublons dans le tableau entier sans l'aide de jeu est, il suffit de créer un temp de tableau et de réitérer le tableau d'origine et vérifiez si le numéro existe en temp tableau alors ne poussez pas dans le tableau reste mis en temp tableau et retour temp tableau en tant que résultat. Veuillez considérer l'extrait de code suivant :
Juste un truc pour supprimer les doublons.
Veuillez vérifier ceci. Il fonctionne pour les trier/tableau non trié. La complexité est O(n^2) même que le tri à bulles.
Oui la complexité peut être encore améliorée avec d'abord les trier et de recherche binaire. Mais c'est assez simple de travailler sur tous les cas sauf un élément négatif (-1). Cela peut également être modifié à l'aide de grande valeur entière au lieu de -1.
Ce code gère les ménagères de tableau contenant plusieurs doubles pour la même valeur et le rendement des éléments uniques.
Je l'ai fait à l'aide de l'échantillon de 12 éléments,
public class Remdup_arr {
}
de sortie est :-
1 1 2 3 4 4 5 6 7 8 6 8
1 8 6 7 5 4 3 2 0 0 0
Utiliser le ArrayUtil classe que vous en avez besoin. J'ai écrit quelques-unes des méthodes autres que la suppression des doublons. Cette classe est mis en œuvre sans l'aide de toute Collecte, de toute les classes du framework.
Espère que ça aide...
Bien la première réponse sera à utiliser hashset qui est conçu pour supprimer les doublons comme Android Killer réponse indique
Approche 2 :-
Mais si vous n'êtes pas autorisé à utiliser ensemble, puis trier d'abord avec quicksort qui sera nlogn et ensuite appliquer
XOR
fonctionnement de la recherche de doublonsOptimisé