Creo que tengo un algoritmo O (n lg U) para esto, donde U es el número más grande. La idea es similar a la de user949300, pero con un poco más de detalle.
La intuición es la siguiente.Cuando está XORingando dos números juntos, para obtener el valor máximo, quiere tener un 1 en la posición más alta posible, y luego de los emparejamientos que tienen un 1 en esta posición, quiere un emparejamiento con un 1 en la siguiente Posible posición más alta, etc.
El algoritmo es el siguiente. Comience encontrando el más alto 1 bit en cualquier parte de los números (puede hacer esto en el tiempo O (n lg U) haciendo O (lg U) trabajo por cada uno de los n números). Ahora, divide el conjunto en dos partes: uno de los números que tienen un 1 en ese bit y el grupo con 0 en ese bit. Cualquier solución óptima debe combinar un número con un 1 en el primer punto con un número con un 0 en ese punto, ya que eso pondría un 1 bit lo más alto posible. Cualquier otro emparejamiento tiene un 0 allí.
Ahora, recursivamente, queremos encontrar el emparejamiento de números del grupo 1 y 0 que tiene el 1 más alto en ellos. Para ello, de estos dos grupos, divididos en cuatro grupos:
- números que empiezan con 11
- números que empiezan con 10
- números que empiezan con 01
- números que empiecen por 00
Si hay números en el grupo 11 y 00 o en los grupos 10 y 01, su XOR sería ideal (comenzando con 11). En consecuencia, si alguno de esos pares de grupos no está vacío, recursivamente calcule la solución ideal de esos grupos, luego devuelva el máximo de esas soluciones de subproblemas. De lo contrario, si ambos grupos están vacíos, esto significa que todos los números deben tener el mismo dígito en su segunda posición. En consecuencia, el XOR óptimo de un número que comienza con 1 y un número que comienza con 0 terminará teniendo el siguiente segundo bit cancelado, por lo que deberíamos simplemente mirar el tercer bit.
Esto da el siguiente algoritmo recursivo que, a partir de los dos grupos de números particionadas por su MSB, da la respuesta:
- Dada grupo 1 y grupo 0 y un índice de bit i:
- Si el índice de bit es igual al número de bits, devuelva el XOR del número (único) en el grupo 1 y el número (único) en el grupo 0.
- Construya los grupos 11, 10, 01 y 00 de esos grupos.
- Si el grupo 11 y el grupo 00 no son vacíos, recursivamente encuentre el XOR máximo de esos dos grupos comenzando en el bit i + 1.
- Si el grupo 10 y el grupo 01 son no vacíos, recursivamente encuentre el XOR máximo de esos dos grupos, comenzando en el bit i + 1.
- Si cualquiera de los pares anteriores fue posible, devuelva el par máximo encontrado por la recursión.
- De lo contrario, todos los números deben tener el mismo bit en la posición i, así devolver el par máximo encontrado examinado bit i + 1 en los grupos 1 y 0.
de comenzar el algoritmo, puede simplemente dividir los números del grupo inicial en dos grupos: números con MSB 1 y números con MSB 0. A continuación, ejecute una llamada recursiva al algoritmo anterior con los dos grupos de números.
Como ejemplo, considere los números 5 1 4 3 0 2.Estos tienen representaciones
101 001 100 011 000 010
Comenzamos de dividir en el grupo 1 y el grupo 0:
101 100
001 011 000 010
Ahora, aplicamos el algoritmo anterior. Dividimos esta en grupos de 11, 10, 01, y 00:
11:
10: 101 100
01: 011 010
00: 000 001
Ahora, no podemos emparejar cualquier 11 elementos con 00 elementos, por lo que sólo recursivo de los grupos 10 y 01. Esto significa que construimos los 100, 101, 010, y 011 grupos:
101: 101
100: 100
011: 011
010: 010
Ahora que estamos abajo a cubos con sólo un elemento en ellos, sólo podemos comprobar los pares 101 y 010 (que da 111) y 100 y 011 (que da 111). Cualquiera de las opciones funciona aquí, por lo que obtenemos que la respuesta óptima es 7.
Pensemos en el tiempo de ejecución de este algoritmo. Observe que la profundidad máxima de recursión es O (lg U), ya que solo hay bits O (log U) en los números. En cada nivel del árbol, cada número aparece en exactamente una llamada recursiva, y cada una de las llamadas recursivas funciona proporcionalmente a la cantidad total de números en los grupos 0 y 1, porque necesitamos distribuirlos por sus bits. En consecuencia, hay niveles O (log U) en el árbol de recursión, y cada nivel funciona O (n), dando un trabajo total de O (n log U).
Espero que esto ayude! ¡Este fue un gran problema!
Una buena apuesta es tomar el mayor y el menor valor desde que son entonces poco probable que 'destruir' las 'buenas' bits altos de la alta pedazos de la pequeña de valor valor durante el proceso xor. –
falló para arr = {8,4,2} la respuesta es 8^4 y 4 no es la más pequeña ... –
@ 500-InternalServerError: Definitivamente será un par de números, uno de los cuales tiene el bit superior establecido y el otro lo ha reiniciado. –