Interleave array in Konstante Raum
Lief ich über die folgenden sample job interview Frage. Wie kann ich es lösen?
Angenommen wir haben ein array
a1, a2,... , an, b1, b2, ..., bn.
Ziel ist es, dies zu ändern, array,
a1, b1, a2, b2, ..., an, bn in O(n) Zeit und in O(1) Speicherplatz.
In anderen Worten, wir brauchen eine linear-time-Algorithmus zu ändern, das array im Ort, mit nicht mehr als eine Konstante Menge an zusätzlichem Speicherplatz.
- Es werden Hausaufgaben gemacht, sonst gäbe es keine Algorithmische Komplexität Einschränkungen :P.
- Okay.. um ehrlich zu sein. Ich bin der Vorbereitung für ein job interview. War auf der Suche über die Fragen careercup.com wo ich gefunden dieser. Aber leider keine Lösung.
- Sie sind im wesentlichen der Umsetzung einer nx2 array in place. Eigentlich, wikipedia hat einen Artikel: en.wikipedia.org/wiki/In-place_matrix_transposition
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dieses problem ist nicht so trivial, wie die Menschen machen aus zu sein. Hausaufgaben? LOL.
Dem folgenden link hat die Lösung: http://arxiv.org/abs/0805.1598
Dies ist die Reihenfolge und die Hinweise habe ich mit Stift und Papier. Ich denke, dass es, oder eine Variante, halten, für größere n.
Jede Linie stellt einen anderen Schritt und () bedeutet, was bewegt diesen Schritt, und [] ist das, was verschoben wurde aus dem letzten Schritt. Das array selbst ist als Speicher und zwei Zeiger (eine für L und eine für N) sind erforderlich, um festzustellen, was sich zu bewegen weiter. L bedeutet "letter line" und " N "die Nummer der Zeile" (was verschoben wird).
Beachten Sie die unterschiedlichen "Zeiger springt" - der L-Zeiger immer dekrementiert um 1 (da es nicht gegessen werden in schneller als, dass), aber die N-Zeiger springt nach, wenn es "ersetzt sich selbst" (im Ort, nach unten springen zwei) oder wenn es vertauscht etwas (kein springen, damit der nächste etwas bekommen kann seine go!)
YMMV
Dieses problem ist nicht so einfach, wie es scheint, aber nach einigem nachdenken, den Algorithmus, um dies zu erreichen, ist nicht allzu schlecht. Sie werden bemerken, dass das erste und Letzte element sind bereits vorhanden, so brauchen wir nicht um Sie kümmern. Wir halten Links index-variable, die darstellt, das erste Element in die erste Hälfte des Arrays, die Bedürfnisse geändert. Danach legen wir eine rechts-index-variable auf das erste Element in der 2. Hälfte des Arrays, die Bedürfnisse geändert. Alles was wir jetzt tun, ist die swap-Eintrag in der rechten index-down one-by-one, bis es erreicht die linke index-Element. Erhöhen Sie den linken index von 2, und den rechten index von 1, und wiederholen, bis die Indizes sich überschneiden oder Links geht über den rechten index (rechts-index wird am Ende immer auf den letzten index des Arrays). Erhöhen wir den linken index von zwei in jeder Zeit, weil das Element Links + 1 hat bereits natürlich fiel in Ort.
Pseudocode
Interleaving-Algorithmus in C(#)
Dieser Algorithmus arbeitet in O(1) Speicher (mit der temp-variable, die eliminiert werden konnte mit der addition/Subtraktion-swap-Technik) ich bin nicht sehr gut in der runtime Analyse, aber ich glaube, das ist immer noch O(n), obwohl wir durchführen viele swaps. Vielleicht kann jemand weitere entdecken Sie die Laufzeit-Analyse.
Es heißt in-place-in-shuffle problem. Hier ist die Umsetzung in C++ basierend auf hier.
Test:
Danach
arr[]
wird{0, 5, 1, 6, 2, 7, 3, 8, 4, 9}
.Zuerst die Theorie: Ordnen Sie die Elemente in 'permutation Zyklen'. Nehmen Sie ein element und platzieren Sie es an seine neue position verschieben das element aus, das wird derzeit gibt es. Dann nehmen Sie das verschobene element und steckte es in seine neue position. Dies verdrängt noch ein anderes element, so Spülen und wiederholen. Wenn das element verdrängt gehört zu der position von dem element, dem Sie die ersten Schritte mit, die Sie abgeschlossen haben, ein Zyklus.
Eigentlich, deiner ist ein Spezialfall der Frage, die ich hier, die war: Wie kann Sie anordnen einer array in beliebiger Reihenfolge in O(N) Zeit und O(1) Speicherplatz? In meiner Frage, die Positionen neu geordnet werden beschrieben durch eine Reihe von zahlen, wobei die Zahl auf die N-te position gibt den index von element im ursprünglichen array.
Jedoch, Sie nicht über diese zusätzliche Reihe in der Sie Ihr problem, und die Zuweisung würde es dauern O(N) Speicherplatz. Glücklicherweise können wir berechnen, die den Wert jedes Elements in diesem array on-the-fly, wie dieser:
Ich nicht duplizieren die Neuordnung Algorithmus selbst hier; es sein kann gefunden in der akzeptierten Antwort auf meine Frage.
Edit: Jason hat darauf hingewiesen, die Antwort, die ich verlinkt noch reservieren muss ein array von bools, so dass es O(N) Speicherplatz. Dies ist, weil eine permutation kann aus mehreren Zyklen. Ich habe versucht, die Notwendigkeit beseitigen, für diese Reihe, die für Ihren speziellen Fall, aber ohne Erfolg.. Es scheint nicht zu sein jede brauchbare Muster. Vielleicht kann jemand anders hier helfen können.
done
zu verfolgen, welche Elemente verschoben wurden.Wenn Sie umwandeln können das array in einer verketteten Liste first, wird das problem trivial.