Zwei Stapel können mithilfe eines Arrays mit fester Größe effizient implementiert werden: Stapel Nr. 1 beginnt am linken Ende und wächst nach rechts, und Stapel Nr. 2 beginnt am rechten Ende und wächst nach links. Ist das gleiche für drei Stapel möglich?
Insbesondere ist es möglich, drei Stapel unter den folgenden Bedingungen zu implementieren:
- Sie haben ein Array mit fester Größe, das N Objekte aufnehmen kann.
- Solange die Summe der drei Stapelgrößen <N ist, sollte push () nicht fehlschlagen.
- Sowohl push () als auch pop () sollten O (1) dauern.
- Zusätzlich zum Array können Sie nur O (1) zusätzlichen Speicherplatz verwenden.
Hier sind Beispiele für Lösungen, die diese Anforderungen nicht erfüllen:
- Teilen Sie das Array in 3 feste Teile und verwenden Sie jeden Teil für einen Stapel (verletzt 2).
- Ähnlich wie oben, jedoch mit beweglichen Grenzen zwischen Stapeln (verletzt 3).
- Einfache Implementierungen auf der Basis verknüpfter Listen (Verstöße gegen 4).
Ich akzeptiere nicht triviale Algorithmen oder Unmöglichkeitsbeweise, auch wenn sie nicht alle Bedingungen (1) - (4) genau erfüllen, zum Beispiel einen Algorithmus, bei dem Push / Pop O (1) amortisierte Zeit benötigt oder bei dem die zusätzlicher Speicher ist kleiner als O (N), z. B. O (log N). Oder ein Unmöglichkeitsnachweis, der zeigt, dass beispielsweise der Zugriff auf weniger als 5 Elemente des Arrays pro Push / Pop nicht möglich ist.
quelle
Antworten:
quelle
Sei N die Länge des zugrunde liegenden Arrays. Ich kann mir Stapel als verknüpfte Listen großer Blöcke vorstellen, sodass die Gesamtzahl der Blöcke nicht mehr als O (log2 (N)) beträgt. Platzieren Sie den dritten Stapel zwischen den ersten beiden am Index von N / 2. Wir haben also 3 besetzte Gebiete und 2 freie. Wenn ein Stapel das nächste Element nicht akzeptieren kann, bedeutet dies, dass ein freier Bereich erschöpft ist. Wenn auch der andere erschöpft ist, ist der gesamte Speicher erschöpft. Ansonsten gibt es einen weiteren freien Bereich mit einer Größe von nicht mehr als N / 2. Setzen Sie den übergelaufenen Stapel in diesen freien Bereich fort. so dass die gesamte Konfiguration dem anfänglichen Layout der Stapel ähnelt. Da der freie Speicher jetzt nicht mehr als die Hälfte des Anfangs beträgt, gibt es nicht mehr als log2 (N) solcher Verknüpfungsoperationen. Jede Verknüpfungsoperation erfordert eine feste Speichermenge, um den vorherigen Status des Stapels zu speichern. So,
quelle