La complejidad describe cómo crece el costo de una solución cuando crece su entrada. No intenta predecir milisegundos exactos; permite comparar algoritmos sin depender de un computador, lenguaje o conjunto pequeño de pruebas.
Dos recursos se analizan principalmente:
Tiempo: cantidad de operaciones relevantes.
Espacio: memoria adicional necesaria durante la ejecución.
Antes de escribir O(n), define qué representa n y qué caso estás analizando.
cantidad de bits necesarios para representar un número.
Ejemplo:
TypeScript
functioncontainsCommonValue(
left:readonlynumber[],
right:readonlynumber[],):boolean{for(const a of left){for(const b of right){if(a === b)returntrue;}}returnfalse;}
Si left tiene n elementos y right tiene m, el peor caso es O(nm), no necesariamente O(n²).
El análisis suele usar un modelo RAM simplificado: operaciones como leer un índice, comparar valores pequeños o asignar una referencia cuestan una unidad constante.
Es una abstracción. En la práctica, comparar strings largos, copiar objetos o hacer operaciones con enteros arbitrariamente grandes no siempre cuesta O(1).
Ejemplo:
TypeScript
if(users[index].name === targetName){// The string comparison may depend on the compared length.}
La operación dominante puede incluir la longitud de las claves.
Θ(g(n)) es una cota ajustada: la función está acotada por arriba y por abajo por el mismo crecimiento.
Texto
f(n) ∈ Θ(g(n))
si f(n) ∈ O(g(n)) y f(n) ∈ Ω(g(n))
Para un loop que siempre recorre todos los elementos:
TypeScript
functionsum(values:readonlynumber[]):number{let total =0;for(const value of values){
total += value;}return total;}
El tiempo es Θ(n): hace una cantidad proporcional a n tanto como cota superior como inferior.
En comunicación cotidiana se usa mucho O(n) aunque Θ(n) sea más preciso. Lo importante es no convertir Big O en una afirmación falsa sobre una garantía exacta.
Para entradas grandes, duplicar n aproximadamente duplica el término dominante. La constante 4 y el 20 no cambian la familia de crecimiento:
Texto
T(n) = Θ(n)
Esto no significa que las constantes no importen en producción. Dos algoritmos O(n) pueden diferir mucho en caché, asignaciones o costo de cada operación. Big O responde una pregunta diferente.
for(let i =0; i < values.length; i +=1){for(let j =0; j < values.length; j +=1){inspect(values[i], values[j]);}}
Ejecuta n × n: Θ(n²).
Pero no todo loop anidado es cuadrático:
TypeScript
let right =0;for(let left =0; left < values.length; left +=1){while(right < values.length &&condition(left, right)){
right +=1;}}
Si right nunca retrocede, avanza como máximo n veces durante toda la función. El tiempo puede ser O(n), más el trabajo del loop externo. Debes contar movimientos totales, no multiplicar loops visualmente.
functionlinearSearch(values:readonlynumber[], target:number):number{for(let index =0; index < values.length; index +=1){if(values[index]=== target)return index;}return-1;}
Mejor caso: Θ(1), está al inicio.
Peor caso: Θ(n), está al final o no existe.
Promedio: requiere una distribución sobre posiciones y presencia.
No digas “average O(n/2)”. n/2 sigue siendo Θ(n), y además el promedio necesita supuestos.
functionreverseInPlace(values:number[]):void{let left =0;let right = values.length -1;while(left < right){[values[left], values[right]]=[values[right], values[left]];
left +=1;
right -=1;}}
Generar todos los subsets necesita almacenar hasta 2^n resultados. Una función puede usar solo O(n) de stack auxiliar, pero la salida materializada es exponencial.
functionprefixes(text:string):string[]{const result:string[]=[];for(let index =1; index <= text.length; index +=1){
result.push(text.slice(0, index));}return result;}
Si cada slice copia index caracteres, el trabajo total es:
Texto
1 + 2 + ... + n = Θ(n²)
No cuentes solo iteraciones; cuenta el costo de lo que ocurre dentro.
Una función tiene un loop sobre n elementos y dentro llama array.includes, que puede recorrer m elementos. ¿Cuál es su peor caso?
Respuesta
O(nm). El loop externo ejecuta n veces una búsqueda que puede costar O(m). Si ambos arrays tienen el mismo tamaño, puede escribirse O(n²), pero solo bajo esa relación.