La tâche est clairement de trouver un algorithme qui est O (1) de la longueur N de la liste de nombres requise. Ainsi, que vous ayez besoin des 100 premiers numéros ou des 10 000 premiers numéros, le temps d’insertion doit être O (1).
L'astuce ici est que bien que cette exigence O (1) soit mentionnée pour l'insertion de liste, la question ne disait rien sur l'ordre du temps de recherche dans l'espace entier, mais il s'avère que cela peut être fait O (1) ainsi que. La solution est alors la suivante:
Organisez une table de hachage avec des nombres pour les clés et des paires de pointeurs de liste liés pour les valeurs. Chaque paire de pointeurs est le début et la fin d'une séquence de liste chaînée. Ce sera normalement juste un élément puis le suivant. Chaque élément de la liste liée va à côté de l'élément avec le prochain numéro le plus élevé. La liste chaînée contient donc la séquence triée des nombres requis. Conservez un enregistrement du nombre le plus bas.
Prendre un nouveau nombre x du flux aléatoire.
Est-il supérieur au dernier numéro le plus bas enregistré? Oui => Étape 4, Non => Étape 2
Appuyez sur la table de hachage avec le nombre que vous venez de prendre. Y a-t-il une entrée? Oui => Étape 5. Non => Prenez un nouveau numéro x-1 et répétez cette étape (il s'agit d'une recherche linéaire descendante simple, tenez compte de moi, cela peut être amélioré et je vais expliquer comment)
Avec l'élément de liste qui vient d'être obtenu à partir de la table de hachage, insérez le nouveau numéro juste après l'élément dans la liste liée (et mettez à jour le hachage)
Prenez le nombre le plus bas que j'ai enregistré (et retirez-le de la liste de hachage).
Appuyez sur la table de hachage avec le nombre que vous venez de prendre. Y a-t-il une entrée? Oui => Étape 8. Non => Prenez un nouveau nombre l + 1 et répétez cette étape (il s'agit d'une recherche linéaire ascendante simple)
Avec un résultat positif, le nombre devient le nouveau nombre le plus bas. Aller à l'étape 2
Pour permettre les doublons, le hachage doit en fait conserver le début et la fin de la séquence d'éléments dupliqués de la liste chaînée. Ajouter ou supprimer un élément à une clé donnée augmente ou diminue donc la plage indiquée.
L'insert ici est O (1). Les recherches mentionnées sont, je suppose, quelque chose comme: O (différence moyenne entre les nombres). La différence moyenne augmente avec la taille de l'espace de nombre, mais diminue avec la longueur requise de la liste de nombres.
La stratégie de recherche linéaire est donc assez faible si l’espace numérique est grand (par exemple, pour un type int de 4 octets, 0 à 2 ^ 32-1) et N = 100. Pour contourner ce problème de performances, vous pouvez conserver des ensembles de haltables parallèles, dans lesquels les nombres sont arrondis à des magnitudes supérieures (par exemple, 1, 10, 100, 1000) pour obtenir les clés appropriées. De cette manière, vous pouvez passer à la vitesse supérieure pour effectuer les recherches requises plus rapidement. La performance devient alors un O (log numberrange), je pense, qui est constant, c’est-à-dire O (1) également.
Pour clarifier cela, imaginez que vous avez le numéro 197 à portée de main. Vous frappez la table de hachage des 10, avec «190», elle est arrondie à la dizaine la plus proche. N'importe quoi? Donc, vous descendez dans 10 secondes jusqu'à atteindre 120, puis vous pouvez commencer à 129 dans la table de hachage 1s, puis essayez 128, 127 jusqu'à ce que vous atteigniez quelque chose. Vous avez maintenant trouvé où dans la liste liée insérer le nombre 197. Tout en l'insérant, vous devez également mettre à jour la table de hachage 1s avec l'entrée 197, la table de hachage 10s avec le nombre 190, 100 avec 100, etc. 10 fois le journal de la plage de numéros.
Je me suis peut-être trompé dans certains détails, mais comme il s'agit de l'échange de programmeurs et du contexte d'interviews, j'espère que ce qui précède constitue une réponse suffisamment convaincante à cette situation.
EDIT J'ai ajouté quelques détails supplémentaires ici pour expliquer le schéma de hachage parallèle et expliquer en quoi les mauvaises recherches linéaires mentionnées précédemment peuvent être remplacées par une recherche O (1). J'ai également compris qu'il n'était bien sûr pas nécessaire de rechercher le prochain nombre le plus bas, car vous pouvez y accéder directement en cherchant dans la table de hachage avec le nombre le plus bas et en passant à l'élément suivant.