Das Kopieren einer normalen verketteten Liste in linearer Zeit ist offensichtlich trivial. Der einzige Teil, der dies interessant macht, ist der "zufällige" Zeiger. Vermutlich meinen Sie mit "zufällig" wirklich, dass er auf einen anderen zufällig gewählten Knoten in derselben verketteten Liste zeigt. Vermutlich soll die Kopie der verketteten Liste genau dieselbe Struktur wiederherstellen - d.h., die 'next'-Zeiger erstellen eine lineare Liste, und die anderen Zeiger verweisen auf dieselben relativen Knoten (zum Beispiel, wenn der zufällige Zeiger im ersten Knoten der Originalliste auf den fünften Knoten in der Originalliste zeigte, dann würde der zufällige Zeiger in der Duplikatliste auch auf den fünften Knoten der Duplikatliste zeigen.
Das in N2-Zeit zu machen, ist ziemlich einfach. Zunächst wird die Liste normal dupliziert, wobei der zufällige Zeiger ignoriert wird. Dann gehen Sie durch die Originalliste einen Knoten nach dem anderen und gehen für jeden Knoten erneut durch die Liste, um herauszufinden, auf welchen Knoten der Liste der zufällige Zeiger verwies (d.h., wie viele Knoten Sie über die next
-Zeiger durchlaufen müssen, um einen next
-Zeiger zu finden, der dieselbe Adresse wie der random
-Zeiger des aktuellen Knotens enthält. Dann durchlaufen Sie die Duplikatliste und stellen das umgekehrt dar - finden Sie die Adresse des Nten Knotens und setzen Sie das in den zufälligen Zeiger des aktuellen Knotens.
Der Grund, warum dies O(N2) ist, sind hauptsächlich diese linearen Suchen nach den richtigen Knoten. Um O(N) zu erreichen, müssen diese Suchen mit konstanter Komplexität anstelle von linearer Komplexität durchgeführt werden.
Der offensichtliche Weg, dies zu tun, wäre der Aufbau einer Hashtabelle, die die Adresse jedes Knotens in der Originalliste auf die Position dieses Knotens in der Liste abbildet. Dann können wir ein Array erstellen, das die Adressen der Knoten in der neuen Liste enthält.
Mit diesen ist es ziemlich einfach, die zufälligen Zeiger zu reparieren. Zuerst gehen wir durch die Originalliste über die next
-Zeiger, duplizieren die Knoten und bauen unsere neue Liste über die next
-Zeiger verbunden auf, lassen aber die zufälligen Zeiger unverändert. Dabei fügen wir die Adresse und Position jedes Knotens in die Hashtabelle ein und die Adresse jedes Knotens in der neuen Liste in unser Array.
Wenn wir damit fertig sind, gehen wir die alte Liste und die neue Liste im Gleichschritt durch. Für jeden Knoten in der alten Liste sehen wir auf die Adresse im zufälligen Zeiger dieses Knotens. Wir schlagen die mit dieser Adresse verbundene Position in unserer Hashtabelle nach, erhalten dann die Adresse des Knotens in der neuen Liste an dieser Position und setzen sie in den zufälligen Zeiger des aktuellen Knotens in der neuen Liste. Dann gehen wir zum nächsten Knoten in der alten und neuen Liste über.
Wenn wir fertig sind, werfen/wir zerstören sowohl die Hashtabelle als auch das Array, da unsere neue Liste nun die Struktur der alten dupliziert und wir die zusätzlichen Daten nicht mehr benötigen.
1 Stimmen
Der erste Zeiger zeigt auf welchen Knoten? Der "nächste Knoten" ergibt aus dem Kontext, den ich lese, keinen Sinn.
12 Stimmen
Fehlt mir etwas? Warum würdest du nicht einfach die Liste genau einmal durchlaufen, indem du den Zeiger auf den nächsten Knoten verwendest und die Liste auf diese Weise kopierst?
1 Stimmen
Ich vermute, dass das Ziel der Interviewfrage war, den Kandidaten dazu zu bringen, dem Interviewer Fragen zu stellen, wie zum Beispiel nach dem Zweck der Zeiger - denn sonst scheint die Frage zu einfach für ein Interview zu sein (es sei denn, es handelte sich um ein Telefon-Vorstellungsgespräch).
2 Stimmen
Ich denke, der Punkt der Frage ist, wie man mit dem Zufallszeiger umgeht. Es ist einfach, eine verkettete Liste (mit nur einem nächsten Knotenzeiger) in Ordnung n zu kopieren. Ich nehme an, dass die Kopie auch ihre eigenen Zufallszeiger haben muss. Ob diese unabhängig zufällig sein können oder ob sie die gleichen Zuordnungen wie die Originalliste haben müssen, wäre eine gute Frage, die man dem Interviewer stellen könnte.
0 Stimmen
@mawicks Wahrscheinlich ist die Absicht, dass Sie die zufälligen Zeiger kopieren müssen. Wenn Sie sie unabhängig voneinander randomisieren können, ist diese Frage lächerlich einfach, da Sie einfach die Liste linear durchlaufen und die festen Zeiger kopieren und die zufälligen Zeiger randomisieren könnten. Das Kopieren der zufälligen Zeiger ist die Herausforderung...
0 Stimmen
EDITIERHINWEIS: Ich habe eine Frageänderung rückgängig gemacht, da wir in dieser "Interview"-Frage davon ausgehen müssen, dass der Text wörtlich wiedergegeben wird.
0 Stimmen
"Zufällige" Zeiger im Kontext der Frage bedeutet, dass er auf jeden Knoten in der Liste zeigen kann, nicht nur auf den nächsten Knoten. Die Frage besteht darin, eine genaue Kopie der Originalliste zu erstellen, wobei die zufälligen Zeiger auf die entsprechenden Knoten in der Kopie gesetzt werden. Das Problem kann leicht gelöst werden, indem eine assoziative Struktur wie eine Hashmap oder ein Wörterbuch verwendet wird. Es wird zu einer größeren Herausforderung, wenn man iteriert und die Lösung in konstanter Speicherplatzimplementiert werden soll.