¿Cuál es la forma más rápida de encontrar el valor Kth más pequeño en una lista sin ordenar sin ordenar?

8

Mi algoritmo inicial:

  1. Compare el elemento 0 con cualquier otro elemento, haciendo un seguimiento de cuántos elementos son menores.
  2. Repita para cada elemento hasta que se encuentre un elemento que sea mayor que exactamente (k-1).

Supongo que esto tomaría en el peor de los casos. ¿Se puede lograr un tiempo de ejecución más rápido sin ordenar la lista?O(norte2)

POR QUÉ
fuente
¿Puedes crear una segunda lista y ordenarla? Es decir, ¿puedes crear una lista de los k valores más pequeños?
jmoreno

Respuestas:

10

Use el algoritmo de selección para tiempo lineal https://en.m.wikipedia.org/wiki/Selection_algorithm

Eugene
fuente
2
En particular, Median of Medians, de Blum et al., 1973, resuelve el problema de selección en el peor tiempo lineal. Probablemente el algoritmo más elegante que he visto.
Quicksort
66
Aunque esto responde a la pregunta, se recomienda hacer una descripción propia, no solo un enlace.
Mal
4

Desafortunadamente no puedo comentar, pero tengo que publicarlo como respuesta.

De todos modos, podría intentar usar un montón mínimo en su matriz no ordenada, debería poder obtener una complejidad de tiempo de O (n + k * logn).

Luca Giorgi
fuente
3
Desafortunadamente no puedo comentar, pero tengo que publicarlo como respuesta. - lo cual fue bueno, ya que las respuestas como tu publicación no pertenecen a los comentarios. Los comentarios son para mejorar las preguntas, no para respuestas cortas o similares.
Wrzlprmft
1
Mh, siento que la mía no es una respuesta completa para ser honesto, no he dado detalles sobre por qué o cómo el uso de un montón mínimo podría reducir la complejidad del tiempo, es por eso que sentí que pertenecía más en un comentario que en una respuesta
Luca Giorgi
Depende de si se debe usar min-heap o max-heap. k
Mal
3

El algoritmo Quickselect puede hacer eso en O (n) complejidad promedio, es uno de los algoritmos de selección más utilizados según Wikipedia .

Se deriva de QuickSort y, como tal, sufre una complejidad O (n²) en el peor de los casos si utiliza un pivote incorrecto (un problema que se puede evitar en la práctica).

El algoritmo en pocas palabras: después de pivotar como en QuickSort, solo desciende hacia el lado inferior o superior de la matriz, dependiendo de cuál de ellos tiene el elemento que estás buscando.

Néstor Demeure
fuente
2

Crea un montón de tamaño máximok. Lo invariable es que el montón siempre contienek elementos más pequeños observados hasta ahora.

  1. Insertar el primero k elementos de la lista en el montón
  2. Para cada elemento restante yo en la lista:
    • dejar METRO ser el elemento máximo en el montón
    • Si yo<METRO, luego borre METRO e inserte yo en el montón

Al final, el montón contendrá el k elementos más pequeños en la lista.

Buscar el elemento máximo tiene un costo constante. El costo de inserción y eliminación esO(k). La complejidad temporal de este método esO(norte.Iniciar sesiónk)

Behrouz Babaki
fuente
1
Max-heap o Min-heap, depende de k> n / 2.
Mal
@Evil Desea verificar si i es más pequeño que cualquiera de los elementos del montón. Por lo tanto, desea saber si es más pequeño que el más grande de ellos. Buscar el elemento máximo es O (1) en max-heap, pero no en min-heap.
Behrouz Babaki
1
Cierto. Imagine que k = 1 o k = n, ¿usaría el mismo montón en ambos casos? ¿Tal vez es posible usar el min-montón de alguna manera cuando es más rápido? (Sé que lo es, tienes +1 de mí, solo un poco, no te preocupes).
Mal
1
@ Mal Tienes razón. Descarté tu comentario a toda prisa. Cuando k> n / 2, uno puede usar un método similar para almacenar los elementos (nk) más grandes en un montón mínimo. Los elementos eliminados del montón son lo que queremos.
Behrouz Babaki