Daten, die Struktur zu finden, median
Dies ist eine interview-Frage. Entwerfen Sie eine Klasse, die speichert Ganzzahlen und bietet zwei Operationen:
void insert(int k) int getMedian()
Ich denke, dass ich verwenden können, BST, so dass insert
O(logN) und getMedian
O(logN) (für getMedian
sollte ich hinzufügen-die Anzahl der rechts - /Kinder für jeden Knoten).
Nun Frage ich mich, ob dies ist die die meisten effiziente Lösung und es gibt keine bessere.
- Mit Ihrer Regelung, die Sie verbessern können
getMedian
zuO(1)
: schauen Sie mal nach, nach jedem einfügen (die nicht Schaden, um die Komplexität) und den Wert speichern. - Für eine alternative Struktur, denken, priority queueS.
- Könnten Sie bitte näher erläutern, wie Sie zu verbessern
getMedian
O(1)? - Ich meine, dass Ihre Daten-Struktur haben würde, die Daten Mitglied
int currentMedian;
. Sofort nach dem einfügen eines Elements in Ihre BST, finden die neuen median, und speichern diesen Wert incurrentMedian
vor der Rückkehr voninsert
. Dann können Sie implementierenint getMedian() { return currentMedian; }
, dieO(1)
. - Weiter nachdenken, können Sie wahrscheinlich etwas zu tun mit einer skip-Liste zu. Einfügungen, die in rechnen/amortisieren
O(log(n))
, und Sie können verfolgen, die median Knoten (und ob die Anzahl der Elemente gerade oder ungerade ist). Dann jedes mal, wenn Sie einfügen, brauchen Sie nur, um zu überprüfen, ob Sie den median einen Schritt nach Links oder rechts, abhängig davon, ob Sie Bild auf das Links oder rechts von der alten median und ob die neue Größe gerade oder ungerade ist.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie 2 Haufen, die wir als
Left
undRight
.Left
ist einMax-Heap
.Right
ist einMin-Heap
.Die Insertion erfolgt über:
x
ist kleiner als die Wurzel derLeft
dann fügen wirx
zuLeft
.x
zuRight
.Left
hat die Anzahl der Elemente, die größer als 1 ist von der Anzahl der Elemente vonRight
, dann nennen wir Extrahieren-MaxLeft
und legen Sie es aufRight
.Right
hat die Anzahl der Elemente, die größer ist als die Anzahl der Elemente vonLeft
, dann rufen Sie Extract-Min aufRight
und legen Sie es aufLeft
.Der median ist immer die Wurzel von
Left
.Also die insertion erfolgt in
O(lg n)
Zeit und immer den median erfolgt inO(1)
Zeit.Sehen diese Stack Overflow Frage für eine Lösung, umfasst zwei Haufen.
Würde es schlug ein array von Ganzzahlen, die Hexe führt eine Sortierung beim einfügen mal mit einem sort-Algorithmus speziell für integer - (http://en.wikipedia.org/wiki/Sorting_algorithm) wenn Sie wählen Sie Ihre Kandidaten unter O < O(log(n)) und ein array verwenden, dann getMedian würde der index die Hälfte der Größe wäre O(1), Nein? Es scheint mir möglich zu tun, besser als log(n) + log(n).
Plus, indem Sie ein wenig flexibler können Sie Ihre Leistung verbessern, indem Sie Ihr sort-Algorithmus nach den Eigenschaften Ihrer Eingabe (die Eingabe fast sortiert oder nicht sortiert ...).
Ich bin ziemlich Autodidakt in der informatik, aber das ist die Art, wie ich es tun würde: einfacher ist besser.
insert
istO(n)
, aber wenn die Anzahl der gespeicherten Werte ist klein, dies ist wahrscheinlich der beste Weg.Könntest du überlegen, ein self-balancing tree, auch. Wenn der Baum ist vollständig ausgeglichen, dann wird der root-Knoten ist median. Sagen, der Baum ist eine Ebene tiefer an einem Ende. Dann, Sie müssen nur wissen, wie viele Knoten gibt es in den tieferen Seite auf, wählen Sie den richtigen median.
(log n)
Ebenen tief in den Baum, da es entweder den linken Knoten des rechten teilbaums oder anderen rechten Knoten des linken teilbaums. So dass Sie brauchen, um die Strecke etwas mehr als nur den root-Knoten und Teilbaum Größen, um den Zugang der median inO(1)
, sondern die Wurzel allein reicht fürO(log n)
.