Je pense à différentes solutions pour un problème. Supposons que nous avons des listes liées K triées K et nous les fusionnons en un. Toutes ces listes ont ensemble des éléments. P>
La solution bien connue consiste à utiliser la file d'attente de priorité et les premiers éléments POP / poussez de toutes les listes et je peux comprendre pourquoi il prend Mais jetons un coup d'œil à une autre approche. Supposons que nous ayons des Ce que nous faisons maintenant signifie généralement jumeler ces listes et la fusionner par paire par paire (si le numéro est impair, la dernière liste, par exemple, pourrait être ignorée aux premières étapes). Cela signifie généralement que nous devons faire l'objet de "arbre" suivant des opérations de fusion: p>
Il semble évident qu'il y aura mon ami m'a dit (il y a deux jours) Cela prendrait O (n log k) code> heure. P>
merge_lists (list1, list2) code> procédure, qui fusionne deux listes triées et qu'il faudrait
O (t1 + t2) code> heure, où
t1 Code> et
T2 code> stand pour
list1 code> et
list2 code> tailles. P>
n1, n2, n3 ... code> stand pour
list1, list2, list3 code> tailles p>
O (N1 + N2) + O (N3 + N4) + O (N5 + N6) + ... Code> Li>
O (N1 + N2 + N3 + N4) + O (N5 + N6 + N7 + N8) + ... Code> Li>
O (N1 + N2 + N3 + N4 + .... + nk) code> li>
ul>
journal (k) code> de ces lignes, chacun d'entre eux implémentant des opérations
O (n) code>, alors heure pour
Fusion (List1, List2, ..., Listk) Code> L'opération serait effectivement égale
O (n log k) code>. Em> p> p>
O (k n) code> heure. Donc, la question est-elle - ai-je f% ck jusqu'à quelque part ou est-ce qu'il s'est trompé à ce sujet? Et si j'ai raison, pourquoi cette approche «Diviser et conquérir» ne peut être utilisée à la place de l'approche de la file d'attente prioritaire? Em> strong> p>
4 Réponses :
Dans votre description, cela sonne comme votre processus est en effet O (N log K). Cela fonctionnera également, vous pouvez donc l'utiliser. P>
J'utiliserai personnellement la première version avec une file d'attente prioritaire, car je soupçonne que ce sera plus rapide. Ce n'est pas plus rapide dans le sens grossier, mais je pense que si vous travaillez réellement le nombre de comparaisons et que les magasins prises par les deux, la deuxième version prendra plusieurs fois plus de travail. P>
Ceci est ou vous pouvez pousser tous les éléments dans le vecteur dans O (2 * journal (k) * n) code> Ceci est
O (n * journal (k)) code> et vous ne pouvez pas avoir la pire complexité car Vous seulement
2n code> ajout à la file d'attente prioritaire dans
o (journal (k)) code>. P>
o (2n) code>. Et triez-le dans
O (2n * journal (2n)) code>. Ensuite, vous avez
O (2n + 2n * journal (2n)) code>, c'est
O (n * journal (n)) code>, exacer votre
k = n < / code>; p>
De manière générale, je voulais seulement savoir si je suis juste dans mon analyse, sans prendre les constantes avant N log K code> en compte. Probablement, si ce serait un goulot d'étranglement dans mon code, j'utiliserais l'algorithme de la file d'attente prioritaire.
Il exécute en effet dans O (n * log k) code>, mais n'oublie pas, que
o (n * log k) code> est un sous-ensemble de
O (n * k) code>. C'est à dire. Votre ami n'est pas faux non plus. p>
On dirait une brillante façon de sauver notre amitié :))
Si vous avez un petit nombre de listes à fusionner, ce schéma par paire est susceptible d'être plus rapide qu'une méthode de file d'attente prioritaire, car vous avez extrêmement peu d'opérations par fusion: une seule comparaison et deux réaffectations de pointeur par élément (pour passer à une nouvelle liste individuellement liée). Comme vous l'avez montré, il est Mais les meilleurs algorithmes de la file d'attente prioritaires sont, je crois, O (n log k) code> (
journal k code> manipulation des étapes
n code> articles chacun). P>
O (sqrt (log K)) code> ou
O (journal de journal u) code> pour insérer et supprimer (où < code> u code> est le nombre de priorités différentes) - si vous pouvez hiérarchiser avec une valeur au lieu d'avoir à utiliser un comparateur - donc si vous fusionnez des éléments pouvant être donnés par exemple Priorités entière, et
k code> est grand, alors vous êtes meilleur à une file d'attente prioritaire. p>
Je pense vraiment que ça vaut la peine de profilage. Cette analyse théorique peut parfois en tirer profit, mais j'essaierai généralement de déterminer après ce que K fait que mon approche commence à manquer de comparer à l'approche de la file d'attente prioritaire. Merci pour votre réponse.
HM, je suppose que c'est pire que le priority_queue Algo car il utilise beaucoup de mémoire supplémentaire. Pourtant, il est plus facile de mettre en œuvre ... hm :)
N code> Dans ce problème définit le nombre total d'éléments dans toutes les listes et non le nombre moyen d'éléments pour l'une des listes.
Je peux comprendre qu'il y aura du nombre de lignes, mais pouvez-vous s'il vous plaît expliquer pourquoi chaque ligne est O (n)? Par exemple, dans la première rangée, il n'y aurait pas de k * o (n)?
Il y aurait n k éléments qui seraient touchés quelles que soient la stratégie que vous utilisez. Donc, la complexité ne peut pas être amenée de O (n i> k).