Ejercicio 05 — Two-sum basico

Dificultad: rojo · Módulo 07 (Diccionarios y sets)

Enunciado

Two-sum basico: encuentra los dos indices cuya suma es target usando dict

Diagramas de flujo

Diagrama de flujo (actividad) del ejercicio 05

Diagrama de flujo (grafo) del ejercicio 05

Cómo se resuelve

El “two-sum” es el ejercicio que enseña por qué un diccionario convierte una búsqueda lenta en una rápida: en vez de probar todas las parejas, recordamos lo que ya vimos y preguntamos al dict en tiempo constante.

  1. visto = {} — un diccionario donde la clave es un número de la lista y el valor su índice. Es nuestra “memoria” de lo que ya hemos recorrido.
  2. for i, num in enumerate(nums)enumerate nos da a la vez el índice i y el valor num, que necesitamos para poder devolver posiciones.
  3. complemento = target - num — para cada número calculamos qué otro número haría falta para llegar al target. Si tenemos num y buscamos que sumen target, el que falta es target - num.
  4. if complemento in visto: — aquí está la clave. Preguntar si el complemento ya apareció es una búsqueda en el diccionario, que gracias al hashing es O(1): no recorre todo lo visto, va directo. Si está, ya tenemos la pareja y devolvemos [visto[complemento], i].
  5. visto[num] = i — si el complemento aún no estaba, guardamos el número actual con su índice para que futuros números puedan encontrarlo a él como su complemento. Así una sola pasada O(n) resuelve el problema.

Trampa habitual: hacerlo con dos bucles anidados que prueban todas las parejas (O(n^2)). Funciona en listas pequeñas pero se dispara con muchas. El truco del dict es cambiar tiempo por memoria: gastamos algo de espacio guardando lo visto a cambio de que cada búsqueda sea instantánea. Ojo también con guardar el número en el dict ANTES de comprobar su complemento: si lo haces al revés, un caso como [3, 3] con target 6 podría emparejar un número consigo mismo por error.

Para practicar — cópialo y complétalo

Pega este esqueleto y completa los TODO. Es la mejor forma de aprender: inténtalo antes de mirar la solución.

# Curso de Python — Modulo 07: Diccionarios y Sets
# Ejercicio 05 — PRACTICA (rellena los TODO)
# Enunciado: Two-sum basico: encuentra los dos indices cuya suma es target usando dict
# Dificultad: rojo
# Ejecutar: python3 ej05_practica.py
 
def two_sum(nums, target):
    # TODO: crea un dict vacio llamado "visto"
    #       guardara { numero: indice } para los numeros ya procesados
    visto = None
 
    # TODO: recorre nums con enumerate() para obtener (indice i, numero num)
    for i, num in enumerate(nums):
        # TODO: calcula el complemento: target - num
        complemento = None
 
        # TODO: comprueba si el complemento ya esta en "visto"
        #       si SI: devuelve [visto[complemento], i]  (los dos indices)
        #       si NO: guarda visto[num] = i  (este numero puede ser complemento futuro)
        pass
 
    return []  # no se encontro solucion
 
 
# Casos de prueba — no modifiques esta parte
casos = [
    ([2, 7, 11, 15], 9),    # esperado: [0, 1]
    ([3, 2, 4], 6),          # esperado: [1, 2]
    ([3, 3], 6),             # esperado: [0, 1]
]
 
for nums, target in casos:
    resultado = two_sum(nums, target)
    print(f"nums={nums}, target={target} -> {resultado}")

Solución — cópiala y ejecútala

# Curso de Python — Modulo 07: Diccionarios y Sets
# Ejercicio 05 — MODELO (resuelto)
# Enunciado: Two-sum basico: encuentra los dos indices cuya suma es target usando dict
# Dificultad: rojo
# Ejecutar: python3 ej05_modelo.py
 
def two_sum(nums, target):
    """
    Para cada numero, calcula su complemento (target - num).
    Si el complemento ya esta en el dict, encontramos la pareja.
    Si no, guardamos el numero actual y su indice en el dict.
    Complejidad: O(n) tiempo, O(n) espacio.
    """
    visto = {}  # clave: numero, valor: indice donde aparecio
 
    for i, num in enumerate(nums):
        complemento = target - num
        if complemento in visto:
            return [visto[complemento], i]
        visto[num] = i
 
    return []  # no se encontro solucion
 
# Casos de prueba
casos = [
    ([2, 7, 11, 15], 9),    # esperado: [0, 1]
    ([3, 2, 4], 6),          # esperado: [1, 2]
    ([3, 3], 6),             # esperado: [0, 1]
]
 
for nums, target in casos:
    resultado = two_sum(nums, target)
    print(f"nums={nums}, target={target} -> {resultado}")

Ejecútalo en el navegador

▶ Visualízalo paso a paso en Python Tutor — ve cómo cambian las variables línea a línea.

Cómo usarlo

Pega el código en un fichero y ejecútalo con tu toolchain habitual (o el botón de Ejecutar de tu editor). Antes de mirar la solución, intenta completar tú el esqueleto: es la mejor forma de aprender.

Conexiones