Nivel: Intermedio
Tema: Algoritmos básicos, “dos punteros”, eficiencia, validación de entradas, tests con pytest
Objetivo: Combinar dos listas ya ordenadas en una sola lista ordenada, en tiempo lineal, sin usar sorted() sobre la lista completa.
Enunciado
Crea una función llamada merge_listas_ordenadas(a, b) que:
- Reciba dos valores
ayb. - Si
aobesNone, trate ese valor como lista vacía. - Si
aobno es una lista (list), lanceTypeError. - Asuma que ambas listas están ordenadas de menor a mayor.
- Devuelva una nueva lista que contenga todos los elementos de
ayb, también ordenada. - No use
sorted()ni.sort()para resolver el problema completo.
(La idea es practicar el algoritmo de merge en O(n + m).)
Para este reto, asume que los elementos son comparables entre sí (por ejemplo, todos números).
Ejemplos
merge_listas_ordenadas([1, 3, 5], [2, 4, 6])→[1, 2, 3, 4, 5, 6]merge_listas_ordenadas([1, 2, 2], [2, 3])→[1, 2, 2, 2, 3]merge_listas_ordenadas([], [1, 2])→[1, 2]merge_listas_ordenadas(None, [1])→[1]merge_listas_ordenadas("123", [1])→ TypeError
Pistas
- Usa dos índices:
iparaa,jparab. - Compara
a[i]conb[j]y añade el menor al resultado. - Avanza el índice del que tomaste el elemento.
- Al final, añade lo que quede de la lista que aún tenga elementos.
Solución explicada (paso a paso)
- Si
aobesNone, lo convertimos a[]. - Validamos que ambos sean listas.
- Inicializamos:
i = 0,j = 0resultado = []
- Mientras queden elementos en ambas listas:
- añadimos el menor de
a[i]yb[j] - avanzamos
ioj
- añadimos el menor de
- Añadimos el resto de la lista que aún tenga elementos.
- Devolvemos
resultado.
Ejecuta:
pytest -q
Variantes para subir de nivel (opcional)
- Merge descendente (de mayor a menor)
- Merge de listas de diccionarios por una clave (ej.
"fecha") - Detectar si las listas no están ordenadas y lanzar error (validación extra)
- Implementar “merge generator” (yield) para streaming
Lo que aprendiste
- El patrón de “dos punteros”
- Cómo lograr O(n+m) sin ordenar de nuevo
- Manejo de duplicados preservando orden
- Tests para algoritmos deterministas
Accede al código completo y a los tests en GitHub para ejecutar y modificar la solución localmente.
Continúa con Reto #17 — Contar ocurrencias con collections.Counter (comparativa) para aprender cuándo simplificar código usando la librería estándar sin perder claridad.