Dada una lista única y ordenada de enteros, cree un árbol de búsqueda binaria equilibrado representado como una matriz sin utilizar la recursividad.
Por ejemplo:
func( [1,2,3,5,8,13,21] ) => [5,2,13,1,3,8,21]
Antes de comenzar, una pista: podemos simplificar este problema una tonelada para que no tengamos que pensar en los enteros de entrada (¡ni en ningún objeto comparable para el caso!).
Si sabemos que la lista de entrada ya está ordenada, su contenido es irrelevante. Simplemente podemos pensarlo en términos de índices en la matriz original.
Una representación interna de la matriz de entrada se convierte en:
func( [0,1,2,3,4,5,6] ) => [3,1,5,0,2,4,6]
Esto significa que, en lugar de escribir algo que tenga que tratar con objetos comparables, realmente solo necesitamos escribir una función que asigne desde el rango [0, n) a la matriz resultante. Una vez que tenemos el nuevo orden, simplemente podemos aplicar la asignación a los valores de la entrada para crear la matriz de retorno.
Las soluciones válidas deben:
- Acepte una matriz de elementos cero y devuelva una matriz vacía.
- Acepte una matriz entera de longitud n y devuelva una matriz entera
- De longitud entre n y la siguiente potencia más alta de 2 menos 1. (por ejemplo, para el tamaño de entrada 13 regrese en cualquier lugar entre 13 y 15).
- Matriz que representa un BST donde el nodo raíz está en la posición 0 y la altura es igual a log (n) donde 0 representa un nodo faltante (o un
null
valor similar si su idioma lo permite). Los nodos vacíos, si están presentes, solo deben existir al final del árbol (por ejemplo,[2,1,0]
)
La matriz de enteros de entrada tiene las siguientes garantías:
- Los valores son enteros con signo de 32 bits mayores que cero.
- Los valores son únicos.
- Los valores están en orden ascendente desde la posición cero.
- Los valores pueden ser escasos (es decir, no adyacentes entre sí).
El código más conciso por recuento de caracteres ascii gana, pero también estoy interesado en ver soluciones elegantes para cualquier idioma en particular.
Casos de prueba
Las salidas para matrices simples que contienen 1
a n
para diversos n
. Como se describió anteriormente, los 0
s finales son opcionales.
[]
[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]
fuente
Respuestas:
Rubí , 143
Es una versión comprimida (más o menos) del siguiente código que básicamente hace un BFS en el árbol.
Además, debido a que es BFS, no DFS, un requisito de solución no recursiva no es significativo, y pone a algunos idiomas en desventaja.
Editar: Solución fija, ¡gracias a @PeterTaylor por su comentario!
fuente
Java , 252
Ok, aquí está mi intento. He estado jugando con operaciones de bits y se me ocurrió esta forma directa de calcular el índice de un elemento en el BST a partir del índice en la matriz original.
Versión comprimida
La versión larga sigue a continuación.
fuente
int[] b(int[] a)
se expresa tan bien comoint[]b(int[]a)
.a.length
en la matriz de asignación. Cámbialo as
. Deshágase del espacio entrefor (
varias veces. Cada bucle for crea unint i=0
y tambiénint t=0
. Crea conn
(int n=0,i,t;
) y luego soloi=0
en los bucles yt=1
dentro. Declare el internolong x
ylong I
cons
y simplemente inicialice en el bucle (long s=a.length,I,x;
yx=..
/I=..
). No debería necesitar espacios alrededor del binario AND&
.I=I|..
se puede escribirI|=..
fuente
No estoy seguro de si esto se ajusta exactamente a su requisito de nodos vacíos al final del árbol y ciertamente no ganará ningún premio por brevedad, pero creo que es correcto y tiene casos de prueba :)
fuente
Golfscript (
9989)Básicamente, un puerto directo de mi solución Python, funciona casi de la misma manera.
Probablemente se puede mejorar bastante con más "golfismos", ya mejorado en 10 caracteres con la entrada de @ petertaylor :)
fuente
!{;}{}if
solo puede ser!{;}*
porque!
garantiza regresar0
o1
. Puede usar tokens no alfabéticos para las variables, por lo que si usa en^
lugar der
, en|
lugar dex
, en&
lugar dey
que puede eliminar todo ese espacio en blanco.Java 192
Asigna el índice en la entrada al índice en la salida
Versión larga:
fuente
Wolfram Mathematica 11, 175 Bytes
La función
g[l]
toma como entrada aList
(pl={1,2,3,4,...}
. Ej. ) Y devuelve aList
de la forma deseada. Funciona de la siguiente manera:x[a_]:=Floor@Min[i-#/2,#]&@(i=Length[a]+1;2^Ceiling@Log2[i]/2)
toma una lista y encuentra la raíz del BST asociado.i=Length[a]+1
atajo para la longitud de la lista2^Ceiling@Log2[i]/2
límite superior en el valor de la raízMin[i-#/2,#]&@(...)
Mínimo de los dos argumentos donde#
representa lo que está dentro del(...)
l//.{...}
Aplicar repetidamente las reglas de reemplazo que siguen al
{}->{}
Nada que hacer (este es el caso límite para evitar un bucle infinito)b__List:>(n[Take[b,#-1],b[[#]],Drop[b,#]]&@x[b])
Dividir unList
en{{lesser}, root, {greater}}
Cases[...,_Integer,{m}]
Toma todos los enteros a nivel (profundidad)m
Table[...,{m,1,x[l]}]
Para todosm
hastax[l]
(que es más de lo necesario en realidad).Se puede probar ejecutando
Esta implementación no incluye ceros finales.
fuente
Pitón (
175171)Bastante condensado, aún bastante legible;
Devuelve el resultado, por lo que puede recorrerlo o (para fines de visualización) imprimirlo como una lista;
fuente
Java
Esta es una solución de cálculo directo. Creo que funciona, pero tiene un efecto secundario pragmáticamente inocuo. La matriz que produce puede estar corrupta, pero no de ninguna manera que afecte las búsquedas. En lugar de producir 0 nodos (nulos), producirá nodos inalcanzables, es decir, los nodos ya se habrán encontrado anteriormente en el árbol durante la búsqueda. Funciona mapeando la matriz de índices de una potencia regular de una matriz de árbol de búsqueda binaria de 2 tamaños en una matriz de árbol de búsqueda binaria de tamaño irregular. Al menos, creo que funciona.
Aquí hay una versión más condensada (solo la función y los nombres emparejados). Todavía tiene el espacio en blanco, pero no me preocupa ganar. Además, esta versión en realidad toma una matriz. El otro simplemente tomó un int para el índice más alto en la matriz.
fuente
GolfScript (
79 7770 caracteres)Como el ejemplo en la pregunta usa una función, he hecho de esto una función. Eliminar el
{}:f;
para dejar una expresión que toma la entrada en la pila y deja el BST en la pila ahorraría 5 caracteres.Demostración en línea (nota: la aplicación puede tardar un poco en calentarse: se agotó el tiempo de espera dos veces antes de ejecutarse en 3 segundos).
Con espacios en blanco para mostrar la estructura:
fuente
J , 52 bytes
la función toma una lista ordenada y regresa en orden de árbol binario
Observe que los árboles tienen una forma idéntica pero el nivel inferior se acorta
`1:
comenzar con 1<.@(2&^.)@>:@#
iterar por el piso de log2 (longitud + 1)+: , >:@+:@i.@>:@#
loop: agrega el doble del último vector con números impares 1,3 .. 2 * longitud + 1# /:@{.
tomar solo la cantidad requerida de artículos y obtener sus índices de clasificación/:
aplicar esos índices de clasificación a la entrada dadaTIO
fuente
Python 2 , 107 bytes
Golf de la respuesta de Joachim Isaksson , Input es un singleton que contiene la lista.
Pruébalo en línea!
fuente