Recientemente, me encontré con un problema clásico para las entrevistas: buscar el número máximo de puntos en una línea recta (en un plano, coordenadas enteras). La idea de una búsqueda exhaustiva se me ocurrió de inmediato, lo que tiene una complejidad de tiempo obvia en O (n ^ 2), pero me pareció que debería haber algo más, al menos alguna alternativa en O (n * log (n)) . Después de media hora, ¡incluso se encontró algo mejor!
Una declaración más detallada del problema con ejemplos de entrada-salida está en GeeksForGeeks y LeetCodeAl principio noté que puede resolver fácilmente el problema solo para líneas horizontales o verticales, agregando la X / Y de cada punto en el diccionario. ¿Y cuál es la diferencia entre las otras líneas? ¿Solo una pendiente? ... ¡Pero es reparable!
Por lo tanto, decidí que era posible recorrer la lista completa de puntos varias veces rotándolos. ¡Y se obtiene la solución en O (n)! Aunque con un gran coeficiente. Realmente espero no haber inventado una bicicleta :)
Visualizado, se ve más o menos así:
mi primer GIF casero, no me regañes :)
Es interesante observar que la
implementación posterior
de una búsqueda exhaustiva tomó más líneas de código.
El gráfico con las mediciones del tiempo de ejecución de mi algoritmo de rotación y la enumeración completa según el número de puntos se encuentra en el encabezado.
Aproximadamente 150 puntos muestran la ventaja de la complejidad lineal en el tiempo (con los coeficientes utilizados en el código anterior). Como resultado, este algoritmo tiene las siguientes desventajas:
- La precisión no es absoluta.
- El tiempo de ejecución en pequeños conjuntos de puntos es largo.
En general, esto se corrige fácilmente mediante una selección competente de coeficientes: para conjuntos simples, ROT_COUNT = 36 en lugar de 2000 es suficiente, lo que acelera el código más de 50 veces.
Y tales ventajas:
- Funciona con calma con coordenadas fraccionarias.
- La complejidad temporal es lineal, lo que se nota en grandes conjuntos de datos.
Una tabla con medidas
está disponible aquí . El código fuente completo del proyecto con ambos algoritmos y varias comprobaciones
está en GitHub .
Actualización Quiero señalar una vez más que este algoritmo tiene ventajas y desventajas, no lo defiendo como un reemplazo ideal para la fuerza bruta, acabo de describir una posible alternativa interesante, que en algunos casos puede ser más apropiada.