Este algoritmo es O (1) espacio (con algo de trampa), O (n) tiempo (promedio), necesita la matriz de origen para ser no-const y lo destruye al final. También limita los valores posibles en la matriz (se deben reservar tres bits de cada valor para el algoritmo).
La mitad de la respuesta ya está en la pregunta. Usa hashmap. Si un número es golpeado dos veces, use la diferencia de índice, actualice el mejor resultado hasta ahora y elimine este número del hashmap para liberar espacio. Para convertirlo en O (1) espacio, simplemente reutilice la matriz fuente. Convierta la matriz a hashmap en contexto.
Antes de pasar un elemento de matriz a la célula HashMap, recuerde su valor y posición. Después de esto, puede sobrescribirse de manera segura. Luego use este valor para calcular una nueva posición en el hashmap y sobrescribirlo. Los elementos se mezclan de esta manera hasta que se encuentra una celda vacía. Para continuar, seleccione cualquier elemento que no esté reordenado. Cuando se reordena todo, cada int pair es definitivamente golpeado dos veces, aquí tenemos un hashmap vacío y un mejor valor de resultado actualizado.
Un bit reservado se utiliza mientras que la conversión elementos de la matriz a las células HashMap. Al principio está despejado. Cuando se reordena un valor a la celda hashmap, este bit se establece. Si este bit no está configurado para el elemento sobreescrito, este elemento simplemente se procesa para ser procesado a continuación. Si este bit está configurado para que se sobrescriba el elemento, aquí hay un conflicto, elija el primer elemento no utilizado (con este bit no configurado) y sobrescríbalo en su lugar.
2 bits más reservados se utilizan para encadenar valores conflictivos. Codifican las posiciones donde la cadena se inicia/finaliza/continúa. (Es posible optimizar este algoritmo para que solo se necesiten 2 bits reservados ...)
Una celda hashmap debe contener estos 3 bits reservados, el índice del valor original y cierta información para identificar este elemento de forma exclusiva. Para que esto sea posible, una función hash debe ser reversible para que parte del valor pueda restaurarse dada su posición en la tabla. En el caso más simple, la función hash es solo ceil(log(n))
bits menos significativos. Valor de la tabla consta de 3 campos:
3
bits reservados
32 - 3 - (ceil(log(n)))
bits de orden superior del valor original
ceil(log(n))
bits para la posición de los elementos de la matriz original
Complejidad de tiempo es O (n) solo en promedio; la complejidad del peor caso es O (n^2).
Otra variante de este algoritmo es transformar la matriz a hashmap secuencialmente: en cada paso m
teniendo 2^m
primeros elementos de la matriz convertidos a hashmap. Algunas matrices de tamaño constante se pueden intercalar con el hashmap para mejorar el rendimiento cuando m
es bajo. Cuando m
es alto, debe haber suficientes pares int, que ya están procesados y ya no necesitan espacio.
Creo que puede hacerlo más rápido ... solo una pista: en su ejemplo, después de encontrar que para 'a [0]' la distancia es '5', no necesita verificar más valores en absoluto, ya que el tamaño si el conjunto es '6'. – lapk
@AzzA Eso acelera las cosas con seguridad, sin embargo, no afecta la tasa de crecimiento asintótico lineal. –
¿Es esta una pregunta de entrevista? –