Skip to content

Introduccion al Pensamiento Algoritmico

Prologo

Como resolver problemas de manera eficiente? Quizas te hayas enfrentado a esta duda: el mismo problema, el codigo de alguien se ejecuta en segundos, mientras que el de otra persona sigue girando durante minutos. La diferencia suele estar en el algoritmo. Este capitulo te guia para comprender los conceptos centrales del pensamiento algoritmico.

Que aprenderas en este articulo?

Despues de completar este capitulo, obtendras:

  • Capacidad de descomposicion de problemas: ante problemas complejos, podras pensar en estrategias como divide y venceras, recursion, etc., en lugar de escribir codigo directamente
  • Capacidad de evaluacion de eficiencia: usar la notacion Big-O para determinar cual de dos soluciones es mas eficiente, en lugar de adivinar por intuicion
  • Pensamiento en complejidad: estimar el tamano de los datos y los requisitos de tiempo antes de escribir codigo, eligiendo el nivel adecuado de algoritmo
  • Base para aprendizaje futuro: sentar las bases para estructuras de datos avanzadas, sistemas distribuidos y aprendizaje automatico
CapituloContenidoConcepto clave
Capitulo 1Busqueda binariaDivide y venceras, O(log n)
Capitulo 2Algoritmos de ordenacionBurbuja, QuickSort, MergeSort
Capitulo 3Analisis de complejidadComplejidad temporal, complejidad espacial

0. Vision general: Que es un algoritmo?

Imagina que necesitas buscar una palabra en un diccionario:

  • Metodo 1: comenzar desde la primera pagina y pasar pagina por pagina (busqueda lineal)
  • Metodo 2: ubicar por la letra inicial y luego buscar por biparticion (busqueda binaria)

Ambos metodos pueden encontrarla, pero la eficiencia es muy diferente. Un algoritmo es un metodo para resolver problemas.

Algorithmic Thinking: Ways to Solve ProblemsDifferent strategies fit different kinds of problems
Binary searchEliminate half each time, O(log n)
Time Complexity Quick Reference
O(1)ConstantBest, such as array access
O(log n)LogarithmicVery good, such as binary search
O(n)LinearCommon, such as traversal
O(n log n)LinearithmicAcceptable, such as quicksort
O(n²)QuadraticSlow, such as bubble sort
O(2ⁿ)ExponentialVery slow, such as brute-force recursion
Core idea:Algorithms are methods for solving problems. A good algorithm can improve efficiency by orders of magnitude. Understanding algorithmic thinking matters more than memorizing individual algorithms.

Indicadores clave de los algoritmos:

IndicadorSignificadoPor que es importante
Complejidad temporalTendencia del tiempo de ejecucion al aumentar los datosPredecir rendimiento con datos a gran escala
Complejidad espacialTendencia del uso de memoria al aumentar los datosEvaluar el consumo de memoria
CorreccionSi siempre obtiene resultados correctosRequisito basico de un algoritmo

Interpretacion fila por fila

Complejidad temporal: se describe con la notacion Big-O. O(n) significa que si los datos se duplican, el tiempo se duplica; O(n^2) significa que si los datos se duplican, el tiempo se cuadruplica.

Complejidad espacial: tambien usa la notacion Big-O. Algunos algoritmos intercambian espacio por tiempo (como las tablas hash), otros intercambian tiempo por espacio (como los algoritmos de compresion).

Correccion: un algoritmo debe dar resultados correctos para todas las posibles entradas. Las condiciones de borde (entrada vacia, entrada enorme) son las mas propensas a errores.


1. Busqueda binaria: eliminar la mitad cada vez

1.1 Principio de la busqueda binaria

Como funciona la busqueda binaria?

Prerrequisito: los datos deben estar ordenados

Proceso:

  1. Encontrar el elemento central
  2. Si el elemento central es igual al objetivo, encontrado!
  3. Si el objetivo es menor que el elemento central, continuar en la mitad izquierda
  4. Si el objetivo es mayor que el elemento central, continuar en la mitad derecha
  5. Eliminar la mitad cada vez, hasta encontrar o determinar que no existe

Complejidad temporal: O(log n)

Analogia cotidiana: el juego de adivinar numeros. Piensa un numero del 1 al 100, cada vez adivinas el central, te digo si es mayor o menor. Con un maximo de 7 intentos puedes acertar (porque 2^7 = 128 > 100).

Prueba aqui abajo: Esta demostracion muestra como funciona la busqueda binaria. Puedes elegir entre busqueda secuencial o binaria para comparar:

Search AlgorithmsHow to find a target in data
Linear search: check items one by one
3
7
2
9
5
1
8
4
6
10
Target number:
Time complexity: O(n)
Use case: unordered arrays
Performance Comparison
Data sizeLinear searchBinary search
10At most 10 stepsAt most 4 steps
100At most 100 stepsAt most 7 steps
1000At most 1000 stepsAt most 10 steps
10000At most 10000 stepsAt most 14 steps

1.2 Por que la busqueda binaria es tan rapida?

Cantidad de datosBusqueda linealBusqueda binaria
100100 veces7 veces
1,0001,000 veces10 veces
1,000,0001,000,000 veces20 veces
1,000,000,0001,000,000,000 veces30 veces

Interpretacion fila por fila

Primera columna (cantidad de datos): cuantos datos se buscan. Se puede ver que la cantidad de datos crece de 100 a 1 billon (un aumento de 10 millones de veces!)

Segunda columna (busqueda lineal): el metodo mas "tonto", comenzando desde el primero y buscando uno por uno. El numero de busquedas es igual a la cantidad de datos; cuantos mas datos, mas busquedas.

Tercera columna (busqueda binaria): el metodo inteligente, eliminando la mitad cada vez. El numero de busquedas solo esta relacionado con el logaritmo de la cantidad de datos; incluso con 1 billon de datos solo necesita 30 veces!

Conclusion de la comparacion: cuando la cantidad de datos alcanza 1 millon, la busqueda lineal necesita 1 millon de veces, la busqueda binaria solo necesita 20 veces; una diferencia de 50,000 veces!

El poder del crecimiento logaritmico

La complejidad temporal de la busqueda binaria es O(log n), lo que significa:

  • 1 billon de datos, maximo 30 busquedas
  • 1 trillon de datos, maximo 40 busquedas

Este es el poder del crecimiento logaritmico: los datos aumentan 1000 veces, las busquedas solo aumentan 10.


2. Ordenacion: convertir lo desordenado en ordenado

2.1 Algoritmos de ordenacion comunes

AlgoritmoComplejidad temporalCaracteristicasEscenario de uso
Ordenacion burbujaO(n^2)Simple pero lentoEnsenanza, datos pequenos
Ordenacion por seleccionO(n^2)Simple pero lentoDatos pequenos
Ordenacion por insercionO(n^2)Rapido con datos casi ordenadosDatos pequenos, casi ordenados
QuickSortO(n log n)El mas rapido en la practicaOrdenacion general
MergeSortO(n log n)Ordenacion estableEscenarios que requieren estabilidad
HeapSortO(n log n)Ordenacion in-placeEscenarios con memoria limitada

Interpretacion fila por fila

Ordenacion burbuja: el algoritmo de ordenacion mas basico, como las burbujas que suben desde el fondo del agua. Simple y facil de entender, pero el mas lento. Adecuado para aprender el concepto de ordenacion, no para uso practico.

Ordenacion por seleccion: cada vez se selecciona el mas pequeno y se coloca al frente. Tambien es simple, pero haga lo que haga con los datos, siempre hace la misma cantidad de comparaciones.

Ordenacion por insercion: como organizar las cartas en la mano al jugar poker. Se inserta cada elemento en la parte ya ordenada. Muy eficiente con datos casi ordenados.

QuickSort: el mas utilizado en desarrollo real. El mas rapido en promedio, pero en el peor caso (datos ya ordenados) degenera a O(n^2).

MergeSort: adopta la idea de "divide y venceras", siempre O(n log n), pero requiere espacio adicional. Adecuado para escenarios que necesitan ordenacion estable.

HeapSort: utiliza la estructura de datos heap para ordenar in-place (sin espacio adicional), pero en la practica suele ser mas lento que QuickSort.

2.2 Por que QuickSort es "rapido"?

Principio de QuickSort

Idea central: divide y venceras

  1. Seleccionar un elemento "pivote"
  2. Colocar los menores que el pivote a la izquierda, los mayores a la derecha
  3. Ordenar recursivamente ambas partes
  4. Combinar los resultados

Por que es rapido?

  • Despues de cada division, el pivote esta en su posicion final
  • En promedio, cada division elimina aproximadamente la mitad de los elementos
  • Complejidad temporal O(n log n)

Analogia cotidiana: organizar una estanteria. Sacas un libro, pones los mas delgados a la izquierda y los mas gruesos a la derecha. Luego repites el proceso con cada pila.

Prueba aqui abajo: Esta demostracion muestra la visualizacion de algoritmos de ordenacion. Puedes generar un array y observar la comparacion entre ordenacion burbuja y QuickSort:

Sorting AlgorithmsPut data into order
50
30
70
40
90
20
60
80
10
55
Choose a sorting algorithm
Select a sorting algorithm to start the demo
Time complexity:
Algorithm Comparison
AlgorithmAverage timeWorst timeSpaceStable
Bubble sortO(n²)O(n²)O(1)
Quick sortO(n log n)O(n²)O(log n)
Merge sortO(n log n)O(n log n)O(n)
Insertion sortO(n²)O(n²)O(1)

3. Recursion: llamarse a si mismo

3.1 La esencia de la recursion

Que es la recursion?

La recursion es una tecnica de programacion donde una funcion se llama a si misma.

Dos elementos clave:

  1. Caso base: cuando se detiene la recursion?
  2. Paso recursivo: como descomponer el problema en subproblemas mas pequenos?

Ejemplo clasico: factorial

js
function factorial(n) {
  if (n <= 1) return 1        // Caso base
  return n * factorial(n - 1) // Paso recursivo
}

Analogia cotidiana: las munecas rusas. Abres una muneca y dentro hay una mas pequena, hasta la mas pequena que ya no se puede abrir.

3.2 Recursion vs Iteracion

CaracteristicaRecursionIteracion (bucle)
Simplicidad del codigoGeneralmente mas concisoPuede ser mas complejo
Consumo de memoriaMayor (pila de llamadas)Menor
RendimientoLigeramente mas lento (sobrecarga de llamadas)Mas rapido
Escenario de usoRecorrido de arboles, divide y vencerasTareas repetitivas simples

Interpretacion fila por fila

Simplicidad del codigo: la recursion generalmente solo necesita unas pocas lineas de codigo para expresar logica compleja (como recorrer estructuras de arbol), mientras que con bucles puede necesitar mas variables y anidamiento.

Consumo de memoria: la recursion usa la "pila de llamadas" para guardar la informacion de cada nivel, como apilar platos; cada nivel de recursion agrega un plato. Los bucles no necesitan esta sobrecarga.

Rendimiento: cada llamada a funcion tiene una sobrecarga (paso de parametros, operaciones de pila, etc.), por lo que la recursion suele ser mas lenta que los bucles.

Escenario de uso: la recursion es buena para problemas que son inherentemente recursivos (como arboles de archivos, arboles DOM); los bucles son buenos para operaciones repetitivas simples (como recorrer arrays).

Trampa de la recursion

Desbordamiento de pila: la recursion es tan profunda que se agota el espacio de la pila de llamadas.

Soluciones:

  • Cambiar a iteracion
  • Usar optimizacion de recursion de cola (algunos lenguajes lo soportan)
  • Limitar la profundidad de recursion

Prueba aqui abajo: Esta demostracion muestra el proceso de llamadas recursivas. Observa como la funcion se llama a si misma:

Recursive Thinking: A Function Calls ItselfBreak a large problem into smaller problems of the same kind
🪆
Nested dolls
Open a large doll and there is a smaller doll inside
Open that one and there is an even smaller one, until the smallest case
That is recursion.
Recursive examples
Factorial: n! = n × (n-1)!
5! = 5 × 4!
4! = 4 × 3!
3! = 3 × 2!
2! = 2 × 1!
1! = 1 (base case)
↑ return 1
↑ return 2 × 1 = 2
↑ return 3 × 2 = 6
↑ return 4 × 6 = 24
↑ return 5 × 24 = 120
Three Elements of Recursion
1
Base case
When should recursion stop? There must be a termination condition.
Example: 1! = 1
2
Recursive call
How does the problem get smaller? Call the same function on a smaller case.
Example: turn n! into (n-1)!
3
Return result
How does the current problem use the result of the subproblem?
Example: the result of n × (n-1)!
✓ Pros
  • Concise code
  • Naturally expresses recursive structures
  • Good for tree and graph traversal
✗ Cons
  • May repeat work
  • Uses stack space
  • Can be harder to debug

4. Algoritmo voraz (greedy): elegir lo mejor en cada paso

4.1 La idea del algoritmo voraz

Que es un algoritmo voraz?

El algoritmo voraz elige en cada paso la opcion que parece mejor en ese momento, esperando obtener la solucion optima global.

Condiciones de aplicacion:

  1. Propiedad de eleccion voraz: lo optimo local puede llevar a lo optimo global
  2. Subestructura optima: la solucion optima del problema contiene las soluciones optimas de los subproblemas

Ejemplo clasico: cambio de monedas

  • Objetivo: usar la menor cantidad de monedas para formar una cantidad
  • Estrategia voraz: cada vez elegir la moneda de mayor valor
  • Resultado: 67 = 50 + 10 + 5 + 1 + 1 (5 monedas)

Analogia cotidiana: al escalar una montana, cada vez eliges el camino mas empinado hacia arriba. Aunque no siempre llegas al pico mas alto, generalmente llegas a una buena posicion.

4.2 Limitaciones del algoritmo voraz

El algoritmo voraz no siempre obtiene la solucion optima

Contraejemplo: cambio de monedas

Si las denominaciones son [1, 3, 4] y necesitas formar 6:

  • Voraz: 4 + 1 + 1 = 3 monedas
  • Optimo: 3 + 3 = 2 monedas

El algoritmo voraz falla aqui!

Leccion: el algoritmo voraz es simple y eficiente, pero no siempre obtiene la solucion optima. Antes de usarlo, hay que demostrar que el problema satisface las condiciones voraces.

Prueba aqui abajo: Esta demostracion muestra el efecto real del algoritmo voraz. Puedes probar diferentes combinaciones de monedas y observar el rendimiento de la estrategia voraz:

Greedy Algorithms: Choose the Best Current MoveLocal optimum → global optimum?
A greedy algorithm chooses the best option available at each step
It hopes a series of local choices reaches a global optimum
Classic problems
Coin Change Problem
Change needed: 37
20
× 1 = 20
10
× 1 = 10
5
× 1 = 5
1
× 2 = 2
Needs 5 coins total
✓ Greedy strategy: choose the largest coin each time
✓ Works for currencies such as RMB and USD
Greedy vs Dynamic Programming
FeatureGreedy algorithmDynamic programming
Decision styleChoose the current best each stepConsider all possibilities and choose the best
OptimalityMay not be globally optimalGuarantees a global optimum
Time complexityO(n) or O(n log n)O(n²) or higher
Best fitLocal optimum → global optimumOverlapping subproblems
✓ Pros
  • Simple to implement
  • Efficient
  • Low space complexity
✗ Cons
  • Does not always guarantee a global optimum
  • Limited applicability
  • Requires an optimality proof

5. Paradigmas de diseno de algoritmos

ParadigmaIdeaAlgoritmo tipicoProblema aplicable
Divide y vencerasDescomponer el problema en subproblemasQuickSort, MergeSortProblemas descomponibles
VorazElegir lo mejor en cada pasoArbol de expansion minima, codificacion de HuffmanProblemas con propiedad voraz
Programacion dinamicaRegistrar las soluciones de los subproblemasProblema de la mochila, camino mas cortoSubproblemas superpuestos
BacktrackingProbar y retroceder si no funcionaOcho reinas, permutaciones completasProblemas de busqueda

Interpretacion fila por fila

Divide y venceras: dividir el problema grande en problemas pequenos, resolverlos por separado y luego combinarlos. Como organizar una casa: primero divides en sala, dormitorio, cocina, limpias cada uno y al final todo esta ordenado.

Voraz: cada vez eliges lo mejor actual, sin considerar las consecuencias a largo plazo. Como comer eligiendo primero tu plato favorito; puede no ser la forma optima de comer, pero es rapido.

Programacion dinamica: recordar resultados intermedios para evitar calculos repetidos. Como tomar notas: la proxima vez que encuentres el mismo problema, buscas la respuesta directamente sin volver a deducirla.

Backtracking: si no funciona, retrocedes y lo intentas de nuevo. Como recorrer un laberinto: si este camino no funciona, vuelves a la ultima interseccion y pruebas otro.

Prueba aqui abajo: Esta demostracion muestra las caracteristicas y escenarios de aplicacion de diferentes paradigmas de diseno de algoritmos:

Algorithm Design ParadigmsCommon patterns for solving problems
Algorithm design paradigms are general strategies for solving problems. Learning them helps you find solution ideas quickly.
✂️
Divide and conquer
Divide, solve, combine
📊
Dynamic programming
Store results to avoid repetition
🎯
Greedy
Local optimum
🔙
Backtracking
Try and retreat
✂️Divide and conquer
Core idea
Split a large problem into smaller independent problems, solve them recursively, then combine the results.
Use cases
Array sortingMatrix multiplicationLarge integer arithmetic
Classic problems
📝
Merge sort
📝
Quick sort
📝
Binary search
📝
Strassen matrix multiplication
Time complexity
O(n log n)
Often much faster than brute force
Paradigm Comparison
ParadigmCore strategyOptimalityUse case
✂️ Divide and conquerSplit → recurse → combineGuarantees optimumProblems that split independently
📊 Dynamic programmingStore subproblem answersGuarantees optimumOverlapping subproblems
🎯 GreedyChoose the best each timeNot always optimalLocal optimum → global optimum
🔙 BacktrackingDepth-first searchGuarantees optimumSmall search spaces that need enumeration
How to choose the right paradigm?
1
Analyze problem features
Are there overlapping subproblems? Is there optimal substructure?
2
Decide whether an optimum is required
Greedy is not always optimal; dynamic programming guarantees an optimum.
3
Consider input size
Backtracking fits small inputs, while divide and conquer fits larger inputs.

6. Resumen: Los algoritmos son el arte de resolver problemas

Usemos una analogia para resumir las distintas ideas algoritmicas:

IdeaAnalogiaPunto clave
Busqueda binariaAdivinar numerosEliminar la mitad cada vez
OrdenacionOrganizar estanteriaEstablecer orden
RecursionMunecas rusasReducir lo grande a lo pequeno
VorazEscoger camino en la montanaOptimo local

Ensenanza central

La esencia de los algoritmos es el equilibrio entre "eficiencia" y "correccion".

  • Un buen algoritmo puede mejorar la eficiencia del programa en varios ordenes de magnitud
  • Pero la optimizacion excesiva puede introducir complejidad
  • Primero asegurar la correccion, luego buscar la eficiencia

Comprender el pensamiento algoritmico es mas importante que memorizar algoritmos especificos:

  • Divide y venceras: descomponer problemas grandes en pequenos
  • Voraz: elegir lo optimo en cada paso
  • Programacion dinamica: registrar las soluciones de los subproblemas
  • Backtracking: probar y retroceder si no funciona

Lectura adicional

  • Introduction to Algorithms: el libro de texto clasico para aprender algoritmos sistematicamente
  • LeetCode: mejorar las habilidades algoritmicas mediante la practica de ejercicios
  • Visualizacion de algoritmos: comprender intuitivamente el proceso de ejecucion de los algoritmos
  • Algoritmos de competicion: aprender tecnicas algoritmicas mas avanzadas