Trouver le 2ème plus grand élément dans un tableau avec le nombre minimum de comparaisons
Pour un tableau de taille N, quel est le nombre de comparaisons nécessaires?
- Combien de stockage temporaire est-il permis?
- Est le tableau déjà trié?
- suppose que ce sera (n-1) comparaisons seulement. Je suis juste à la pensée de tri de l'ensemble de la liste et d'obtenir le deuxième élément de la liste
- Montrer ton code s'il vous plaît.
- pensez tournoi.
- il serait n*log(n) comparaisons. Le tri ne peut pas devenir plus rapide.
- Vous êtes de droite. Irréfléchis de moi. Merci.
- À moins que le tableau est d'entiers. Ensuite, vous pouvez radix-genre, pas de comparaison à tous 😉
- Même alors, cela suppose que vous connaissez les limites inférieure et supérieure sur les entiers :). Radix sort est très utile, mais très limitée. Lorsque de telles contraintes ne sont pas le problème, de son mieux pour assumer n*log(n)
- Plus généralement, la recherche de la k-ième plus grand élément: stackoverflow.com/q/251781/98654
- Pas de limites nécessaires: en.wikipedia.org/wiki/.... Venez pour penser à elle, un tri radix comporte encore en boucle sur les données d'entrée, et une boucle doit comporter une comparaison de la résiliation de la condition. Il n'a pas besoin d'être d'un ordre de comparaison, si, juste une comparaison d'égalité. Mais vous avez raison, la question ne dit rien sur les types de données, donc une réponse adéquate doit assumer données opaques et un comparateur de fonction. Si l'interviewer plutôt fait l'erreur de poser une
int
cas particulier (ou chaîne de caractères à un réel effort), c'est 0 comparaisons... - encore suppose que vous n'êtes pas à l'aide d'un "long" type de données (dans le cas de python), ou un BigInteger (dans le cas de C++) :). Radix sort est malheureusement limitée.
- Un LSD radix de tri permettra de traiter de grands volumes entiers, bien que ce n'est pas ce que j'ai liée.
- Ah, mais il vous manque un problème présent avec "long": la longueur est illimitée. La complexité de radix tri n'est pas O(n), il est O(d*n) où d est le nombre de chiffres. Si les chiffres dépasser la taille de n, alors vous avez effectué pire qu'un O(n^2) trier :P. Il n'a pas d'importance. Ceci est mon dernier commentaire sur le sujet. Radix sort est utile, mais limité 😉
- bien sûr, mais la question n'est pas: "faites ceci dans le plus bas possible de la complexité du temps", c'est "faire le moins possible nombre de comparaisons". 0 les comparaisons gagner si possible, même si c'est O(A(d,n)) temps (la fonction d'Ackermann) 😉
- pourquoi utilisez-vous de la fonction d'Ackermann? (J'ai cherché sur elle, mais ne pouvait pas trouver pourquoi vous avez utilisé dans le temps de la complexité du concept) 🙂
- J'ai trouvé ceci(ajaybadgujar.com/...) la solution est très utile avec un minimum de complexité
Vous devez vous connecter pour publier un commentaire.
L'algorithme optimal utilise n+log n-2 comparaisons. Pensez à des éléments comme des concurrents, et un tournoi est de les classer.
Tout d'abord, comparer les éléments, comme dans l'arbre
cela prend n-1 comparaisons et chaque élément est impliqué dans la comparaison au plus log n fois. Vous trouverez le plus grand élément gagnant.
Le deuxième plus grand élément doit avoir perdu un match pour le gagnant (il ne peut pas perdre un match à un autre élément), de sorte qu'il est le journal de n éléments, le gagnant a joué contre. Vous pouvez trouver lequel d'entre eux à l'aide de log n - 1 comparaisons.
L'optimalité est prouvé par adversaire argument. Voir https://math.stackexchange.com/questions/1601 ou http://compgeom.cs.uiuc.edu/~jeffe/enseignement/497/02-sélection.pdf ou http://www.imada.sdu.dk/~jbj/DM19/lb06.pdf ou https://www.utdallas.edu/~chandra/documents/6363/lbd.pdf
n+log n-2 comparisons … The optimality is proved via adversary argument
- drôle compte tenu de la transmission max candidats besoin de n-1 comparaisons.Vous pouvez trouver la deuxième plus grande valeur avec au plus 2·(N-1) les comparaisons et les deux variables qui détiennent la plus grande et la deuxième valeur la plus élevée:
Utiliser la Bulle de tri ou de Sélection de l'algorithme de tri qui trie le tableau par ordre décroissant. Ne pas trier le tableau complètement. Seulement deux passes. Premier passage donne le plus grand élément et le second passage vous donnera le deuxième plus grand élément.
Pas. des comparaisons de premier passage: n-1
Pas. des comparaisons de premier passage: n-2
Total no. de comparaison pour trouver le deuxième plus grand: 2n-3
Peut-être vous pouvez généraliser cet algorithme. Si vous avez besoin de la 3ème plus grande puis vous faire 3 passes.
Par la stratégie ci-dessus, vous n'avez pas besoin de toutes les variables temporaires comme la Bulle de tri et de Sélection, de tri sont en place le tri algorithmes.
2n-3
.Voici un code qui pourrait ne pas être optimale, mais au moins trouve effectivement le 2ème plus grand élément:
Il faut au moins N-1 comparaisons si le plus grand de 2 éléments sont au début du tableau et au plus 2N-3 dans le pire des cas (l'un des 2 premiers éléments est le plus petit dans le tableau).
cas 1-->9 8 7 6 5 4 3 2 1
cas 2--> 50 10 8 25 ........
cas 3--> 50 50 10 8 25.........
cas 4--> 50 50 10 8 50 25.......
Désolé, code JS...
Testé avec deux entrées:
Ce qui devrait avoir un maximum de un.longueur*2 comparaisons et passe seulement par la liste une fois.
Je sais que c'est une vieille question, mais voici ma tentative de le résoudre, rendant l'utilisation du Tournoi de l'Algorithme. Il est similaire à la solution utilisée par @sdcvvc , mais je suis à l'aide de tableau à deux dimensions pour stocker des éléments.
De faire fonctionner les choses, il y a deux hypothèses:
1) nombre d'éléments dans le tableau est la puissance de 2
2) il n'y a pas de doublons dans le tableau
L'ensemble du processus se compose de deux étapes:
1. la construction d'un tableau 2D en comparant deux par deux éléments. Première ligne du tableau 2D va être l'ensemble du tableau d'entrée. La ligne suivante contient les résultats des comparaisons de la rangée précédente. Nous continuons à des comparaisons sur le nouveau tableau et de continuer à construire le tableau 2D jusqu'à ce qu'un tableau d'un seul élément (le plus grand) est atteint.
2. nous avons un 2D-tableau où la dernière ligne contient un seul élément: la plus grande. Nous continuons d'aller du bas vers le haut, dans chaque tableau de trouver l'élément qui a été "battu" par le plus grand et en la comparant à la "deuxième" de la valeur. Pour trouver l'élément battu par la plus grande, et pour éviter de O(n) comparaisons, il faut stocker l'indice du plus grand élément de la rangée précédente. De cette façon, nous pouvons facilement vérifier les éléments adjacents. À n'importe quel niveau (au-dessus de niveau de la racine),les éléments adjacents sont obtenus:
où rootIndex est l'indice de la plus grande(la racine) de l'élément au niveau précédent.
Je sais que la question demande pour le C++, mais voici ma tentative de le résoudre en Java. (J'ai utilisé des listes au lieu de tableaux, pour éviter le désordre changement de la taille de la matrice et/ou inutiles tableau de calcul de la taille)
Supposons que prévue tableau est inPutArray = [1,2,5,8,7,3] attendus O/P> 7 (deuxième)
La version de PHP de le Gumbo algorithme: http://sandbox.onlinephpfunctions.com/code/51e1b05dac2e648fd13e0b60f44a2abe1e4a8689
En supposant que l'espace n'est pas pertinent, c'est le moindre que je puisse faire. Il nécessite 2*n comparaisons dans le pire des cas, et n comparaisons dans le meilleur des cas:
de l'essayer.
il doit travailler comme un charme. faible complexité.
voici un code java.
Utiliser le comptage de tri et ensuite trouver le deuxième plus grand élément, à partir de l'indice 0, vers la fin. Il devrait y avoir au moins 1 titre de comparaison, au plus
n-1
(quand il n'y a qu'un seul élément!).La solution retenue par sdcvvc en C++11.
Je suis passé par tous les postes ci-dessus, mais je suis convaincu que la mise en œuvre du Tournoi de l'algorithme est la meilleure approche. Considérons l'algorithme suivant posté par @Gumbo
Il est très bon dans le cas où allons-nous trouver le deuxième plus grand nombre dans un tableau. Il a (2n-1) nombre de comparaisons. Mais que faire si vous voulez calculer le troisième plus grand nombre ou de certains kth plus grand nombre. L'algorithme ci-dessus ne fonctionne pas. Vous avez obtenu d'une autre procédure.
Donc, je crois tournoi algorithme approche est la meilleure et c'est ici la lien pour que.
La solution suivante serait de prendre 2(N-1) comparaisons:
Il peut être fait dans n + ceil(log n) - 2 comparaison.
Solution:
il prend n-1 comparaisons pour obtenir le minimum.
Mais pour obtenir le minimum, nous allons organiser un tournoi dans lequel chaque élément seront regroupés par paires. comme un tournoi de tennis et gagnant d'un tour d'aller de l'avant.
Hauteur de cet arbre sera log n depuis que nous avons la moitié à chaque tour.
Idée d'avoir une deuxième, au minimum, qu'il sera battu par minimum candidat dans l'une des tours précédents. Donc, nous avons besoin de trouver le minimum de candidats potentiels (battu par minimum).
Des candidats potentiels seront log n = hauteur de l'arbre
Donc, pas de. de comparaison pour trouver le minimum à l'aide de tournoi est un arbre n-1
et pour la seconde minimum est log n -1
résume = n + ceil(log n) - 2
Voici le code C++
Ref: http://www.ajaybadgujar.com/finding-second-largest-number-from-array-in-javascript/
Une bonne façon avec O(1) fois la complexité serait d'utiliser un max-heap. Appelez le heapify deux fois et vous avez la réponse.
Je suppose, suivez l'algorithme optimal utilise n+log n-2 comparaisons" à partir de ci-dessus, le code que j'ai trouvé qui n'utilise pas d'arbre binaire pour stocker la valeur serait la suivante:
Lors de chaque appel récursif, la taille de la matrice est réduit de moitié.
De sorte que le nombre de comparaisons est:
1ère itération: n/2 comparaisons
2ème itération: n/4 comparaisons
3ème itération: n/8 comparaisons
...
Jusqu'à log n itérations?
Par conséquent, total => n - 1 comparaisons?
En supposant tableau contient 2^n certain nombre de numéros.
Si il y a 6 chiffres, puis 3 numéros de passer au niveau suivant, ce qui n'est pas droit.
Besoin de 8 chiffres => 4 => 2 => 1 numéro => 2^n nombre de nombre
Trier le tableau dans l'ordre croissant puis affecter une variable à la (n-1)ème terme.
Arrays.sort()
).