Además del algoritmo sugerido de "echar un vistazo en la parte superior del montón", que le da complejidad O (n log m) para obtener el top-m de n elementos, aquí hay dos soluciones más.
Solución 1: Use un montón de Fibonacci.
La implementación de PriorityQueue del JDK es un montón binario equilibrado. Debería poder exprimir más rendimiento de una implementación de Fibonacci heap. Se habrá amortizado el inserto de tiempo constante, mientras que la inserción en un montón binario tiene una complejidad Ω (log n) en el tamaño del montón. Si estás haciendo eso para cada elemento, entonces estás en Ω (n log n). Encontrar el top-m de n elementos usando un montón de Fib tiene complejidad O (n + m log n). Combine esto con la sugerencia de que solo inserte m elementos en el montón, y tiene O (n + m log m), que es lo más cercano al tiempo lineal que va a obtener.
Solución 2: recorra la lista M veces.
Debería poder obtener el elemento k-mayor en un conjunto en el tiempo O (n). Simplemente lea todo en una lista y haga lo siguiente:
kthLargest(k, xs)
Pick a random pivot element p from the list
(the first one will do if your list is already random).
Go over the set once and group it into two lists.
Left: smaller than p.
Right: Larger or equal to p.
If the Right list is shorter than k, return kthLargest(k - right.size, Left)
If the Right list is longer than k, return kthLargest(k, right)
Otherwise, return p.
Eso le da O (n) tiempo. Ejecutando ese m veces, debería ser capaz de obtener los objetos top-m en su conjunto en el tiempo O (nm), que será estrictamente menor que n log n para n suficientemente grande y lo suficientemente pequeño m. Por ejemplo, obtener el top-10 de más de un millón de elementos tomará la mitad de tiempo que usar una cola de prioridad de montón binaria, en igualdad de condiciones.
¿Ha ejecutado un generador de perfiles en este código? ¿Cómo está escrito su comparador? –
public int comparar (i ListElement, ListElement j) { \t \t \t \t \t \t \t si (i.getValue() - j.getValue()> 0) return 1; else return -1; } – BigG
Id. Le sugiero encarecidamente que haga un perfil de su código y descubra qué causa exactamente que el código se ejecute más lento de lo que desea. Sin código mostrado y sin información adicional, es difícil responder a esta pregunta. ¿Qué parte está funcionando lento? –