¿Cuál es el algoritmo más rápido para calcular el késimo elemento más pequeño en la unión de dos listas ordenadas de tamaño myn?

Claramente, solo los primeros k elementos de cada lista (M y N) son relevantes, por lo que los elementos restantes pueden ignorarse.

Desde este punto, el problema se puede resolver con una forma modificada de búsqueda binaria, con una gran O de log (k). Para cada elemento [math] a = M [i] [/ math], [math] 0 \ leq i <k [/ math] buscamos en la lista M, buscamos [math] N [j] [/ math ], [matemáticas] j = ka-1 [/ matemáticas]. Aquí hay una implementación de Python:

  def ksmallest (M, N, k):    
     min_poss = max (0, k-len (N) -1)
     max_poss = min (k-1, len (M) -1)
     r = 0
     si k == 1:
         retorno min (M [0], N [0])
     si k == len (N) + len (M):
         retorno máximo (M [-1], N [-1])
     mientras max_poss-min_poss> 0:
         d = max_poss-min_poss
         l = min_poss + (d + 1) // 2
         imprimir (l, k- (l + 1))
         a = M [l]
         b = N [k- (l + 1)]
         imprimir (l, d, a, b)
         si a == b:
             descanso
         si a <b:
             min_poss = l
         más:
             max_poss = l-1
     si l <len (M) -1:
         retorno min (a, b)
     retorno max (a, N [k- (l + 1) -1])

Otra solución que hace log k comparaciones:

Compara los 2 elementos intermedios.
Suponga A [k / 2] Reduzca el problema a encontrar el elemento k / 2 en A [k / 2:] y B [0: k / 2].

La solución de Ben podría tomar 2 log k comparaciones.

Cuando tiene 2 matrices ordenadas y desea encontrar el kth número más grande, puede hacerlo fácilmente en [math] O (k) [/ math] de la siguiente manera:

  • En cada paso, realice un seguimiento de 2 valores más grandes candidatos: uno de cada matriz
  • Deseche el más grande de los 2 y realice un seguimiento del siguiente más grande de esa matriz.
  • Continúa hasta llegar al k’th más grande.

Lo anterior es muy similar al paso de fusión del algoritmo de clasificación de fusión .

Si tenía arreglos [math] m [/ math] ordenados, entonces nuevamente se puede hacer en [math] O (m + k * log m) [/ math] tiempo de manera similar. La diferencia: debe realizar un seguimiento de los valores más grandes de [math] m [/ math] candidato. Esto se puede hacer usando un montón máximo sobre los candidatos, donde cada inserción / eliminación tomaría tiempo [matemático] O (logm) [/ matemático] ya que mantiene el tamaño del montón como [matemático] m [/ matemático] siempre. Se necesitaría tiempo [math] O (m) [/ math] para crear el montón.

Una pequeña observación sobre el algoritmo es que, cuando elimina elementos del candidato, puede terminar una de sus matrices ordenadas completas. Esto se puede solucionar asumiendo que el primer elemento de cada matriz es [math] – \ infty [/ math]

EDITAR: Esta respuesta fue movida de otra pregunta muy similar. Veo que ya hay respuestas bastante buenas aquí.