|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Invité de passage
![]() Inscription : décembre 2012 Messages : 1 ![]() |
Bonjour,
J'ai une liste d'entiers de taille n et je sais qu'il y a seulement k différents entiers dans cette liste. Je voudrais savoir lequel de ces entiers apparait le plus grand nombre de fois en utilisant le fait que k est nettement inférieur à n. En fait j'ai l'impression de presque avoir l'algorithme car je sais le faire si ces entiers vont de 0 à k mais pourtant ça coince... L'unique critère qui m'intéresse ici est la vitesse d'exécution. Je pense que c'est faisable en O(n). Merci d'avance pour votre précieuse aide ! |
|
|
00
|
|
|
#2 |
|
Invité régulier
![]() S. ABIDIInscription : septembre 2011 Messages : 4 ![]() |
Je ne suis pas sûr de comprendre ta question, si j'ai bien compris, ton problème est le suivant:
- Tu as une liste de n nombres dont seulement k nombres différents - Tu veux trouver le nombre qui se répète le plus dans cette liste - k <<< n ça veut dire qu'on tend vers avoir un seul nombre qui se répète n fois dans cette liste Un algorithme que je vois pour résoudre ce problème est de créer un tableau à deux dimensions de taille nx2, disons n colonnes et 2 lignes. La première ligne correspond aux nombres et la deuxième correspond aux nombres d’occurrences de chacun des nombres. Parcourir ta liste et à chaque fois: - Soit tu as un nouveau nombre que tu n'as jamais eu => tu remplis une nouvelle colonne de ton tableau avec les valeurs: {nouveau nombre, 1} - Soit tu as un nombre que t'as déjà eu => tu cherches la colonne de ton tableau et tu incrémentes le nombre de 1 {nombre déjà rencontré, nombre++} Quand tu auras parcouru toute ta liste, il suffira de chercher le nombre d'occurrences le plus élevé dans ton tableau et prendre le nombre correspondant, c'est le nombre que tu cherches. Par contre pour la complexité, je ne sais plus comment la calculer, il me semble bien que ça correspond à O(n) puisqu'on ne fait que parcourir simplement un tableau ou une liste de taille n sans récursivité. |
|
|
00
|
|
|
#3 | ||||||
|
Membre Expert
![]() Yankel ScialomIngénieur en systèmes embarqués Inscription : juin 2004 Messages : 998 ![]() |
Bonjour,
la complexité de l'algorithme proposé est un peu supérieur à O(n). En effet, cet algorithme est en deux parties : d'une part le parcourt de la liste d'entrée (les n nombres), et d'autre part le parcourt de la liste de travail (les k nombres). Dans la première étape, pour chaque élément de la liste d'entrée on doit rechercher un nombre dans la liste de travail ; pour chaque nouveau nombre rencontré on a de plus une insertion dans la liste de travail à faire. Dans la seconde étape, on parcourt la liste de travail. Avec l'implémentation donnée par sabidi on a une complexité en O(nk + k + k) dans le cas moyen (bonne répartition des nombres de la liste d'entré). On peut améliorer ceci en triant la liste de travail (tri par insertion, forcément). Cela nous donne, pour chaque élément de la liste d'entrée, une recherche par dichotomie dans la liste de travail et pour chaque nombre distinct de la liste d'entrée une insertion ; la recherche finale dans la liste de travail est elle inchangée. O(n.logk + k + k). Code :
Code :
Code :
__________________
gasp in touch -- Yankel Scialom |
||||||
|
|
10
|
|
|
#4 |
|
Membre Expert
![]() Ingénieur intégration Inscription : décembre 2012 Messages : 393 ![]() |
Bonjour,
On peut aussi gagner du temps, en mémorisant dans un couplet à part, lors de la création de la liste de travail, le nombre qui à le plus d'occurence. Pour ce faire, il suffit juste de tester l'insertion en cours dans la liste de travail avec le fameux couplet et d'écraser celui-ci avec les valeur du couplet de la liste de travail si celui-ci à déjà un nombre supérieur d'occurence. J'espère avoir été assez claire dans l'idée Cordialement. |
|
|
00
|
|
|
#5 |
|
Membre Expert
![]() Yankel ScialomIngénieur en systèmes embarqués Inscription : juin 2004 Messages : 998 ![]() |
Cela revient sensiblement au même : pour maintenir ton couplet à jour, lors de chaque insertion tu as une opération à faire, soit k opérations au total ; et cette astuce ne te permet que d'économiser le parcours de la liste de k éléments en fin d'algo. On gagne k, mais on perd k.
Ce que tu proposes peut être intéressant, mais c'est au niveau de l'implémentation. Et cela n'est pas notre affaire ici. Cdlt,
__________________
gasp in touch -- Yankel Scialom |
|
|
00
|
|
|
#6 |
|
Membre Expert
![]() Inscription : avril 2004 Messages : 1 246 ![]() |
On peut aussi accélérer en ne parcourant pas les n entiers de ta liste, mais juste p entiers, p < n. Ce qui te donne une approximation, en supposant que la variance entre le nombre d'occurrence des différents nombres est suffisamment grand.
|
|
|
00
|
Copyright © 2000-2013 - www.developpez.com