Hay un asintóticamente más rápida manera de resolver este problema, pero tengo serias dudas sobre si sería correr más rápido en la práctica debido a su tamaño de la ventana (10) es tan pequeño.Si desea aumentar este tamaño, que llamaré k, para que sea más grande, entonces puede considerar optar por un enfoque como el siguiente.
Al utilizar este algoritmo, es necesario mantener una ventana de los k elementos que soporta dos operaciones:
- insertar un nuevo elemento, el desalojo de los más antiguos.
- Devuelve todos los elementos mayores que algún valor.
Una forma de hacerlo sería almacenar todos sus elementos en una estructura de datos que combine un árbol de búsqueda binaria equilibrado y una cola. La cola contiene todos los elementos k almacenados en el orden en que aparecen en la secuencia original, y se utiliza para que podamos recordar qué elemento desalojar cuando necesitamos agregar un nuevo elemento. El BST equilibrado almacena una copia de cada uno de esos elementos almacenados en orden ordenado. Esto significa que se puede implementar las operaciones anteriores como este:
- insertar un nuevo elemento, el desalojo de los más antiguos: Añadir el nuevo elemento a la cola y BST. Luego, quite la cola de la cola para obtener el elemento más antiguo y luego elimínelo de la BST. Tiempo de ejecución: O (log k), ya que la BST tiene k elementos en ella.
- Devuelve todos los elementos mayores que algunos valores: Usando la BST, encuentre el elemento más pequeño al menos tan grande como ese valor en el tiempo O (log n). Luego, escanee el BST y enumere todos los elementos al menos tan grandes como ese elemento. Esto toma el tiempo O (z), donde z es el número total de coincidencias encontradas.
Colectivamente, si tiene n elementos y un total de z pares que necesita insertar en la base de datos, este algoritmo tomará O (n log k + z) tiempo. Para ver esto, tenga en cuenta que hacemos un total de n copias de la operación (1), que toma el tiempo O (log k) cada una. También hacemos n copias de la operación (2), que toma el tiempo O (n log k) para encontrar los sucesores y luego O (z) el tiempo total en todas las iteraciones para listar todos los pares coincidentes.
El tiempo de ejecución asintótico de este algoritmo es bueno en comparación con el algoritmo O (nk) que ha publicado originalmente. Suponiendo que el número de coincidencias no es "realmente enorme" (digamos, del orden de nk), será mucho más rápido a medida que aumenta nyk.
Si los valores que almacena son enteros en un rango pequeño (digamos, 0 - 10,000), puede acelerar esto aún más reemplazando la BST balanceada con una estructura de datos optimizada para enteros, como van Emde Boas tree, que reduce esto a O (n log log k + z). De nuevo, esto solo es más rápido asintóticamente, y si mantiene k constante en 10, esto casi seguro no lo vale.
Espero que esto ayude!
No veo cómo esto es O (n^2) para empezar. Estás recorriendo cada elemento de la matriz y luego observas los siguientes 10 elementos. Así que esto es imo O (10 * N) = O (N), así que en el mejor de los casos puedes reducir un poco la sobrecarga constante - pero probablemente no traerá grandes mejoras si no hay orden o algo sobre los datos – Voo
¿Los datos valores en cualquier orden en particular? –
Estoy de acuerdo con Voo. Usted está mirando una distancia fija adelante independientemente de N, por lo que aunque pueda estar haciendo el mismo trabajo varias veces, es solo una multiplicativa constante multiplicada por N más trabajo, por lo que su ciclo es O (N). –