Erstellen Sie anhand einer eindeutigen, sortierten Liste von Ganzzahlen einen ausgeglichenen Binärsuchbaum, der als Array ohne Verwendung von Rekursion dargestellt wird.
Beispielsweise:
func( [1,2,3,5,8,13,21] ) => [5,2,13,1,3,8,21]
Bevor wir anfangen, ein Hinweis: Wir können dieses Problem um ein Vielfaches vereinfachen, damit wir nicht über die Eingabe-Ganzzahlen (oder ein vergleichbares Objekt) nachdenken müssen.
Wenn wir wissen, dass die Eingabeliste bereits sortiert ist, ist der Inhalt irrelevant. Wir können es uns einfach in Form von Indizes in das ursprüngliche Array überlegen.
Eine interne Darstellung des Eingabearrays wird dann:
func( [0,1,2,3,4,5,6] ) => [3,1,5,0,2,4,6]
Das heißt, anstatt etwas zu schreiben, das mit vergleichbaren Objekten zu tun hat, müssen wir wirklich nur eine Funktion schreiben, die aus dem Bereich [0, n) auf das resultierende Array abgebildet wird. Sobald wir die neue Reihenfolge haben, können wir die Zuordnung einfach wieder auf die Werte in der Eingabe anwenden, um das Rückgabearray zu erstellen.
Gültige Lösungen müssen:
- Akzeptieren Sie ein Array mit null Elementen und geben Sie ein leeres Array zurück.
- Akzeptieren Sie ein Integer-Array der Länge n und geben Sie ein Integer-Array zurück
- Mit einer Länge zwischen n und der nächsthöheren Potenz von 2 minus 1. (z. B. bei Eingangsgröße 13 irgendwo zwischen 13 und 15 zurückgeben).
- Array, das eine BST darstellt, bei der sich der Stammknoten an Position 0 befindet und die Höhe log (n) entspricht, wobei 0 einen fehlenden Knoten darstellt (oder einen
null
ähnlichen Wert, wenn Ihre Sprache dies zulässt). Leere Knoten, falls vorhanden, dürfen nur am Ende des Baumes existieren (zB[2,1,0]
)
Das ganzzahlige Eingabearray hat die folgenden Garantien:
- Werte sind 32-Bit-Ganzzahlen mit Vorzeichen, die größer als Null sind.
- Werte sind einzigartig.
- Die Werte sind ab Position Null aufsteigend sortiert.
- Werte können spärlich sein (dh nicht nebeneinander liegen).
Der knappste Code nach Anzahl der ASCII-Zeichen gewinnt, aber ich bin auch daran interessiert, elegante Lösungen für eine bestimmte Sprache zu finden.
Testfälle
Die Ausgaben für einfache Arrays enthalten 1
bis n
für verschiedene n
. Wie oben beschrieben, sind die nachfolgenden 0
s optional.
[]
[1]
[2,1,0]
[2,1,3]
[3,2,4,1,0,0,0]
[4,2,5,1,3,0,0]
[4,2,6,1,3,5,0]
[4,2,6,1,3,5,7]
[5,3,7,2,4,6,8,1,0,0,0,0,0,0,0]
[6,4,8,2,5,7,9,1,3,0,0,0,0,0,0]
[7,4,9,2,6,8,10,1,3,5,0,0,0,0,0]
[8,4,10,2,6,9,11,1,3,5,7,0,0,0,0]
[8,4,11,2,6,10,12,1,3,5,7,9,0,0,0]
[8,4,12,2,6,10,13,1,3,5,7,9,11,0,0]
[8,4,12,2,6,10,14,1,3,5,7,9,11,13,0]
[8,4,12,2,6,10,14,1,3,5,7,9,11,13,15]
quelle
Antworten:
Rubin , 143
Es ist eine (lose) komprimierte Version des folgenden Codes, die im Grunde ein BFS für den Baum ausführt.
Da es sich um BFS und nicht um DFS handelt, ist die Anforderung einer nicht rekursiven Lösung nicht wesentlich, und es werden einige Sprachen benachteiligt.
Edit: Behobene Lösung, danke an @PeterTaylor für seinen Kommentar!
quelle
Java , 252
Ok, hier ist mein Versuch. Ich habe mit Bitoperationen herumgespielt und mir diese direkte Methode ausgedacht, um den Index eines Elements in der BST aus dem Index im ursprünglichen Array zu berechnen.
Komprimierte Version
Die lange Version folgt weiter unten.
quelle
int[] b(int[] a)
ist genauso gut ausgedrückt wieint[]b(int[]a)
.a.length
in der Array-Zuordnung. Ändern Sie es zus
. Entfernen Sie den Abstand zwischenfor (
mehreren Malen. Jede for-Schleife erzeugt einint i=0
und auchint t=0
. Erstellen Sie mitn
(int n=0,i,t;
) und dann nuri=0
in den Schleifen undt=1
innen. Deklarieren Sie das innerelong x
undlong I
mits
und initialisieren Sie es einfach in der Schleife (long s=a.length,I,x;
undx=..
/I=..
). Sie sollten keine Leerzeichen um das binäre UND benötigen&
.I=I|..
kann geschrieben werdenI|=..
quelle
Ich bin mir nicht ganz sicher, ob dies genau zu Ihrer Anforderung passt, dass leere Knoten am Ende des Baums sind, und es wird sicherlich keine Preise für die Kürze gewinnen, aber ich denke, es ist richtig und es hat Testfälle :)
quelle
Golfscript (
9989)Grundsätzlich funktioniert ein gerader Port meiner Python-Lösung auf die gleiche Weise.
Kann wahrscheinlich mit mehr "Golfismen" einiges verbessert werden, bereits verbessert um 10 Zeichen mit @ petertaylors Eingabe :)
quelle
!{;}{}if
kann nur!{;}*
daran liegen,!
garantiert zurückzukehren0
oder1
. Sie können nicht alphabetische Token für Variablen verwenden, wenn Sie also verwenden^
stattr
,|
stattx
,&
statty
sie alle , dass Leerzeichen zu beseitigen.Java 192
Ordnet den Index in der Eingabe dem Index in der Ausgabe zu
Lange Version:
quelle
Wolfram Mathematica 11, 175 Bytes
Die Funktion
g[l]
nimmt als Eingabe aList
(zBl={1,2,3,4,...}
) und gibt aList
in der gewünschten Form zurück. Es funktioniert wie folgt:x[a_]:=Floor@Min[i-#/2,#]&@(i=Length[a]+1;2^Ceiling@Log2[i]/2)
Nimmt eine Liste und findet die Wurzel des zugehörigen BST.i=Length[a]+1
Abkürzung für die Länge der Liste2^Ceiling@Log2[i]/2
Obergrenze für den Wert der WurzelMin[i-#/2,#]&@(...)
Minimum der beiden Argumente wo#
steht was in der steht(...)
l//.{...}
Wenden Sie die folgenden Ersetzungsregeln wiederholt anl
{}->{}
Nichts zu tun (dies ist der Randfall, um eine Endlosschleife zu vermeiden)b__List:>(n[Take[b,#-1],b[[#]],Drop[b,#]]&@x[b])
Teilen Sie einList
in{{lesser}, root, {greater}}
Cases[...,_Integer,{m}]
Nehmen Sie alle ganzen Zahlen auf Ebene (Tiefe)m
Table[...,{m,1,x[l]}]
Für allem
bisx[l]
(was eigentlich mehr als nötig ist).Es kann durch Laufen getestet werden
Diese Implementierung enthält keine nachgestellten Nullen.
quelle
Python (
175171)Ziemlich komprimiert, immer noch ziemlich lesbar;
Es gibt das Ergebnis zurück, so dass Sie es entweder durchlaufen oder (zu Anzeigezwecken) als Liste ausdrucken können.
quelle
Java
Dies ist eine direkte Berechnungslösung. Ich denke, es funktioniert, aber es hat einen pragmatisch harmlosen Nebeneffekt. Das von ihm erzeugte Array ist möglicherweise beschädigt, hat jedoch keinerlei Auswirkungen auf die Suche. Anstatt 0 (null) Knoten zu erzeugen, werden nicht erreichbare Knoten erzeugt, dh die Knoten wurden bereits früher im Baum während der Suche gefunden. Es funktioniert, indem das Index-Array einer regulären Potenz von 2 binären Suchbaum-Arrays auf ein unregelmäßig großes binäres Suchbaum-Array abgebildet wird. Zumindest denke ich, dass es funktioniert.
Hier ist eine komprimiertere Version (nur die Funktion und die Namen sind aufeinander abgestimmt). Es ist immer noch der weiße Raum, aber ich mache mir keine Sorgen um den Sieg. Auch diese Version nimmt tatsächlich ein Array auf. Der andere hat gerade ein int für den höchsten Index im Array genommen.
quelle
GolfScript (
79 7770 Zeichen)Da das Beispiel in der Frage eine Funktion verwendet, habe ich dies zu einer Funktion gemacht. Wenn Sie das entfernen
{}:f;
, um einen Ausdruck zu hinterlassen, der Eingaben in den Stapel aufnimmt und die BST auf dem Stapel belässt, werden 5 Zeichen gespart.Online-Demo (Hinweis: Die App kann ein wenig aufwärmen. Für mich ist die Zeit zweimal abgelaufen, bevor sie in 3 Sekunden ausgeführt wird.)
Mit Leerzeichen, um die Struktur anzuzeigen:
quelle
J , 52 Bytes
Funktion nimmt eine sortierte Liste und kehrt in binärer Baumreihenfolge zurück
Beachten Sie, dass die Bäume die gleiche Form haben, die untere Ebene jedoch verkürzt ist
`1:
Beginnen Sie mit 1<.@(2&^.)@>:@#
iteriere nach Stockwerk von log2 (Länge + 1)+: , >:@+:@i.@>:@#
Schleife: Fügt das Doppelte des letzten Vektors mit ungeraden Zahlen 1,3 .. 2 * Länge + 1 hinzu# /:@{.
Nehmen Sie nur die erforderliche Anzahl von Elementen und erhalten Sie ihre Sortierindizes/:
Wenden Sie diese Sortierindizes auf die angegebene Eingabe anTIO
quelle
Python 2 , 107 Bytes
Golf von Joachim Isaksson: Input ist ein Singleton, der die Liste enthält.
Probieren Sie es online!
quelle