Contenido del curso
DFS
- 6

Cómo recorre nodos el algoritmo DFS
04:49 min - 7

Implementación de DFS recursivo para búsqueda en árboles
12:10 min - 8

Búsqueda en Profundidad (DFS) para Grafos: Enfoque Iterativo y Recursivo
01:27 min - 9

Inorder, Preorder y Postorder en árboles
07:09 min - 10

Suma de caminos raíz a hoja en árboles
02:04 min - 11

Suma de caminos raíz a hoja con DFS
07:31 min - 12

Playground: Sum Root to Leaf Numbers
- 13

Implementación de Algoritmo DFS en Árboles Binarios con Golang
15:03 min - 14

Número de islas con DFS en matrices
02:32 min - 15

Problema de islas resuelto con DFS
08:50 min - 16

Playground: Number of Islands
- 17

Número de islas con DFS recursivo en Python
10:18 min - 18

Ejercicios Prácticos de Búsqueda en Profundidad (DFS)
02:22 min - 19

Algoritmos de Búsqueda en Profundidad (DFS) en Problemas Comunes
06:19 min
BFS
- 20

Cómo BFS recorre grafos por niveles
02:05 min - 21

Implementación de BFS con colas en Python
08:42 min - 22

Mínimos movimientos del caballo en ajedrez
02:55 min - 23

Minimum Knight's Move con BFS
08:11 min - 24

Playground: Minimum Knights Moves
- 25

Resolución de Problemas de Caballos de Ajedrez con BFS en Python
17:49 min - 26

Propagación BFS en Rotting Oranges
03:50 min - 27

Resolución de Rotting Oranges usando BFS
08:43 min - 28

Playground: Rotting Oranges
- 29

Implementación de BFS para naranjas podridas
23:44 min - 30

Puente más corto entre islas con BFS
03:38 min - 31

Shortest Bridge: combina DFS y BFS
07:35 min - 32

Playground: Shortest Bridge Between Islands
- 33

Shortest Bridge con DFS y BFS en Python
14:57 min - 34

Búsqueda en anchura: Ejercicios prácticos y aplicaciones
03:41 min - 35

Ejercicios avanzados de búsqueda en anchura (BFS) en programación
08:47 min
Backtrack
- 36

Backtracking para encontrar soluciones válidas
04:20 min - 37

Combinaciones de letras en teclado telefónico
01:51 min - 38

Combinaciones de teclado con backtracking
09:19 min - 39

Generación de combinaciones de letras con teclados numéricos en C++
14:08 min - 40

Playground: Letter Combinations of a Phone Number
- 41

Generación de Direcciones IP Válidas a partir de Cadenas Numéricas
03:51 min - 42

Backtracking para generar IPs válidas
28:16 min - 43

Playground: Restore IP Addresses
- 44

Búsqueda de Palabras en Matrices: Solución y Complejidad
02:54 min - 45

Word Search con DFS y backtracking
08:30 min - 46

Playgrund: Word Search
- 47

Búsqueda de palabras en matrices con DFS
18:18 min - 48

Resolución del problema de las n reinas en ajedrez
01:08 min - 49

Ejercicios de Backtracking: Combinaciones y Permutaciones
01:05 min - 50

Combinaciones y Permutaciones con Backtracking
02:14 min
Próximos pasos
Qué es la recursión en programación
Resumen
La recursión es uno de esos conceptos que suena abstracto en programación hasta que lo vives en un ejemplo cotidiano. En pocas palabras, ocurre cuando una función se llama a sí misma para resolver un problema dividiéndolo en versiones más pequeñas. Si estás aprendiendo estructuras de datos o algoritmos, entender cómo funciona te abre la puerta a soluciones más limpias y elegantes.
Qué es la recursión y por qué se compara con cajas dentro de cajas
Imagina que buscas una manilla en tu casa. Abres un cajón, dentro hay una caja de recuerdos, dentro otra de recuerdos familiares, y dentro otra más pequeña con joyas. Ahí, por fin, está la manilla. Repetiste la misma acción (abrir una caja y buscar) sobre una entrada cada vez más pequeña hasta resolver el problema.
Eso es exactamente lo que hace una función recursiva: ejecuta la misma operación, pero cada vez sobre un subconjunto más pequeño del problema, hasta llegar a una condición que detiene el proceso.
¿Qué es la recursión en programación? Es la técnica en la que una función se llama a sí misma con una entrada más pequeña para resolver un problema dividiéndolo en partes manejables.
Si viste El origen, la analogía es la misma: un sueño dentro de un sueño dentro de otro sueño. La diferencia es que en código necesitas decidir cuándo despertar.
Por qué necesitas un caso base en una función recursiva
Sin un punto de salida, una función recursiva se llamaría a sí misma para siempre y caerías en un ciclo infinito. Para evitarlo existe el caso base: la condición que le dice a la función aquí ya encontraste, ya termina.
En el ejemplo de la manilla, el caso base es encontrarla dentro de una caja. En código, suele ser una comparación simple que retorna un valor sin volver a llamarse.
¿Qué pasa si no defino un caso base? La función se llamará indefinidamente y provocará un desbordamiento de pila (stack overflow). Siempre necesitas una condición de parada.
Esta idea es la columna vertebral de cualquier algoritmo recursivo bien escrito.
Cómo aplicar recursión con la secuencia de Fibonacci
La secuencia de Fibonacci es un ejemplo clásico que aparece en matemáticas, naturaleza y arte. Cada número resulta de sumar los dos anteriores: 0, 1, 1, 2, 3, 5, 8, 13 y así infinitamente.
Si quieres calcular Fibonacci de 8, sabes que viene de 3 + 5. Y ese 5 viene de 2 + 3. Y ese 2 viene de 1 + 1. La estructura es naturalmente recursiva: cada resultado depende de dos resultados más pequeños.
Cómo se vería el código de Fibonacci con recursión
La función recibe una posición n y devuelve el valor en esa posición. Estos son los pasos clave:
- Define la función
fib(n). - Si
n == 0, retorna 0 (caso base). - Si
n == 1, retorna 1 (caso base). - En cualquier otro caso, retorna
fib(n-1) + fib(n-2).
python def fib(n): if n == 0: return 0 if n == 1: return 1 return fib(n - 1) + fib(n - 2)
La magia está en la última línea: la función se llama dos veces sobre entradas más pequeñas y suma sus resultados. Cuando n llega a 0 o 1, deja de llamarse y empieza a devolver valores hacia arriba.
Por qué la recursión simple repite cálculos
Aquí viene lo interesante. Si calculas fib(8), tu función calculará fib(6) varias veces, fib(5) varias veces y así. Estás resolviendo los mismos subproblemas una y otra vez, lo que hace al algoritmo lento cuando n crece.
Una forma de optimizarlo es guardar resultados ya calculados para reutilizarlos en lugar de recomputarlos. Esa técnica se conoce como memoization y convierte una recursión costosa en una solución eficiente.
Cuándo conviene usar recursión en lugar de un ciclo
Muchos problemas también se resuelven con un ciclo iterativo. La pregunta es cuándo elegir cada uno:
- Usa iteración cuando el problema es lineal y el ciclo se lee con claridad.
- Usa recursión cuando el problema se divide naturalmente en subproblemas más pequeños del mismo tipo.
- Usa recursión cuando el código resulta más legible y expresivo que un ciclo equivalente.
Los casos típicos donde la recursión brilla incluyen recorrer árboles, navegar estructuras anidadas, algoritmos divide y vencerás y secuencias matemáticas como Fibonacci o el factorial.
Ahora un reto para ti: en la función fib que vimos, ¿cómo evitarías repetir cálculos? ¿Qué condición o estructura agregarías para guardar los resultados ya conocidos? Déjalo en los comentarios y nos leemos en la próxima clase.