Puede hacerlo de manera bastante eficiente con la selección rápida en [math] O (\ log n) [/ math] pasadas de la matriz, para un tiempo de ejecución total de [math] O (n \ log n) [/ math].
(En la implementación estándar de la selección rápida, uno realmente dividiría la matriz en subconjuntos que se ubican a ambos lados del pivote, produciendo un tiempo de ejecución más rápido [matemática] O (n) [/ matemática]. Pero esos subconjuntos podrían no caber en la memoria, entonces Supongo que eso no está permitido aquí. En cambio, solo recordamos los límites en el subconjunto de interés actual y pasamos por todo el conjunto cada vez, ignorando cualquier cosa fuera de los límites).
from itertools import islice from random import randint inf = float("inf") def select(lst, index): lo, hi = -inf, inf count = len(lst) while True: i = randint(0, count - 1) pivot, = islice((x for x in lst if lo <= x < hi), i, i + 1) if count == 1: break lo_count = sum(1 for x in lst if lo <= x < pivot) if index < lo_count: hi = pivot count = lo_count else: lo = pivot count -= lo_count index -= lo_count return pivot
Al elegir [math] k – 1 [/ math] pivotes aleatorios en lugar de solo uno, donde puede colocar enteros [math] k [/ math] en la memoria, puede reducir el número de pases a [math] O (\ log_k n) [/ matemáticas]. Esta variante todavía se ejecuta en tiempo [matemático] O (n \ log n) [/ matemático] pero exhibe una mejor localidad de referencia.
- ¿Qué tecnología utiliza X ?: ¿Cómo implementan las empresas de análisis (Mixpanel, KISSMetrics, etc.) el análisis de embudos?
- ¿Se pueden implementar dfs sin recursividad?
- ¿Cuál es la solución a este décimo problema polinómico de clase?
- ¿Qué es mejor entre la búsqueda binaria y el árbol de búsqueda binaria para buscar?
- ¿Se puede usar la GPU para optimizar los algoritmos gráficos?