Complejidad espacial y compensaciones
Mida el espacio auxiliar de las pilas de llamadas y las estructuras de datos auxiliares, y reconozca las compensaciones entre tiempo y espacio en la memoización y los algoritmos in-place.
Complejidad espacial y compensaciones es una lección gratuita de Coding Interview Prep en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Coding Interview Prep, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Coding Interview Prep incluye 4 lecciones en total.
¿Qué mide la complejidad espacial?
La complejidad espacial mide la memoria adicional más allá de la entrada, denominada espacio auxiliar. Unas pocas variables requieren O(1); un array de resultados o un mapa hash requieren O(n). Consulte el código.
# O(1) auxiliary space
def sum_array(nums):
total = 0 # one integer variable
for n in nums:
total += n # constant extra space
return total
# O(n) auxiliary space
def copy_array(nums):
return list(nums) # allocates n slots
print(sum_array([1, 2, 3, 4])) # 10
print(copy_array([1, 2, 3, 4])) # [1, 2, 3, 4]Espacio de la pila de llamadas en la recursión
Cada llamada recursiva añade un marco de pila, por lo que la profundidad determina el espacio utilizado. La recursión lineal es O(n); el recorrido DFS de un árbol equilibrado es O(log n). Una versión iterativa puede controlarlo mejor.
import sys
def recursive_sum(n):
if n == 0: return 0
return n + recursive_sum(n - 1)
# Space: O(n) stack frames
def iterative_sum(n):
total = 0
while n > 0:
total += n
n -= 1
return total
# Space: O(1)
print(recursive_sum(100)) # 5050
print(iterative_sum(100)) # 5050Espacio de merge sort: O(n)
Merge sort necesita un espacio adicional O(n) para sus arrays temporales. Ese es el coste de una ordenación estable O(n log n); heap sort ahorra espacio, pero no es estable. Consulte el código.
import tracemalloc
tracemalloc.start()
def merge_sort(arr):
if len(arr) <= 1: return arr
m = len(arr) // 2
l = merge_sort(arr[:m]) # new list
r = merge_sort(arr[m:]) # new list
out, i, j = [], 0, 0
while i < len(l) and j < len(r):
if l[i] <= r[j]: out.append(l[i]); i+=1
else: out.append(r[j]); j+=1
return out + l[i:] + r[j:]
data = list(range(1000, 0, -1))
merge_sort(data)
_, peak = tracemalloc.get_traced_memory()
print(f'Peak memory: {peak} bytes') # proportional to nAlgoritmos in situ: espacio O(1)
Un algoritmo in situ modifica directamente la entrada sin almacenamiento adicional proporcional, como al invertir un array con dos punteros. Así, el espacio utilizado se mantiene en O(1). Consulte el código.
def reverse_inplace(arr):
l, r = 0, len(arr) - 1
while l < r:
arr[l], arr[r] = arr[r], arr[l] # swap
l += 1
r -= 1
# Space: O(1) -- only two pointer variables
def rotate_right(arr, k):
'''Rotate array right by k positions in-place.'''
n = len(arr)
k %= n
arr.reverse() # O(1) space
arr[:k] = arr[:k][::-1]
arr[k:] = arr[k:][::-1]
a = [1, 2, 3, 4, 5]
rotate_right(a, 2)
print(a) # [4, 5, 1, 2, 3]Equilibrio entre tiempo y espacio: Two-Sum
El equilibrio entre tiempo y espacio aparece en todas partes. Two-Sum requiere O(n^2) de tiempo y O(1) de espacio, o bien O(n) de tiempo y O(n) de espacio mediante un mapa hash. Mencione ambas opciones y pregunte qué factor es más importante.
# O(n^2) time, O(1) space
def two_sum_slow(nums, target):
for i in range(len(nums)): # O(n)
for j in range(i+1, len(nums)): # O(n)
if nums[i] + nums[j] == target:
return [i, j]
return []
# O(n) time, O(n) space
def two_sum_fast(nums, target):
seen = {} # O(n) space
for i, n in enumerate(nums):
comp = target - n
if comp in seen: # O(1) lookup
return [seen[comp], i]
seen[n] = i
return []
print(two_sum_fast([2, 7, 11, 15], 9)) # [0, 1]Espacio de memoización frente a tabulación
La memoización de arriba abajo cuesta O(n) por la memoización más O(n) por la pila; la tabulación de abajo arriba evita la pila. Conservar solo las últimas filas reduce el espacio a O(1): programación dinámica optimizada en espacio.
# Fibonacci: O(n) space with full table
def fib_table(n):
dp = [0] * (n + 1)
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
# O(1) space: keep only last two values
def fib_optimal(n):
if n <= 1: return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
print(fib_table(10)) # 55
print(fib_optimal(10)) # 55Espacio de un mapa hash: O(n)
Un mapa hash suele ser el coste espacial O(n) de las soluciones: un conjunto de elementos vistos para los visitados o un mapa de frecuencias para contar. Indíquelo siempre: «O(n) de tiempo y O(n) de espacio» es la respuesta completa.
def contains_duplicate(nums):
# O(n) time, O(n) space
seen = set()
for n in nums:
if n in seen: return True
seen.add(n)
return False
def group_anagrams(words):
# O(n*m) time, O(n) space (m = avg word length)
from collections import defaultdict
groups = defaultdict(list)
for w in words:
groups[tuple(sorted(w))].append(w)
return list(groups.values())
print(contains_duplicate([1,2,3,1])) # True
print(group_anagrams(['eat','tea','tan','ate','nat','bat']))Análisis espacial de algoritmos de grafos
Los grafos requieren un espacio considerable: una lista de adyacencia ocupa O(V + E), el conjunto de visitados y la cola de BFS ocupan O(V), y la recursión de DFS puede alcanzar una profundidad O(V). Exprese el espacio de los grafos en función de V y E.
from collections import deque
def bfs(graph, start):
# Space: O(V) for visited set + O(V) for queue
visited = set() # O(V)
queue = deque([start]) # O(V) max
order = []
while queue:
node = queue.popleft()
if node in visited: continue
visited.add(node)
order.append(node)
for nb in graph.get(node, []):
queue.append(nb)
return order
g = {0:[1,2], 1:[3], 2:[3], 3:[]}
print(bfs(g, 0)) # [0, 1, 2, 3]Problemas de asignación en cadenas y arrays
Las asignaciones ocultas pueden introducir un espacio O(n): el slicing crea una lista nueva, y usar + con cadenas dentro de un bucle es O(n^2). sorted() crea una copia, pero lst.sort() modifica la estructura in situ. Consulte el código.
# Hidden allocations:
nums = [1, 2, 3, 4, 5]
# Creates a NEW list -- O(n) space
slice_copy = nums[1:4] # [2, 3, 4]
# Creates a NEW sorted list -- O(n) space
sorted_copy = sorted(nums) # nums unchanged
# Sorts IN PLACE -- O(1) extra space
nums.sort()
print(slice_copy) # [2, 3, 4]
print(sorted_copy) # [1, 2, 3, 4, 5]
print(nums) # [1, 2, 3, 4, 5]Reconocer los equilibrios espaciales en entrevistas
Indique de antemano la complejidad espacial. Si la persona entrevistadora quiere reducirla, algunas opciones habituales son utilizar programación dinámica de abajo arriba en lugar de memoización, o una ordenación in situ en lugar de un mapa hash. Consulte el código.
# Problem: find if array has duplicates
# Option 1: O(1) time-per-check, O(n) space
def has_dup_hash(nums):
return len(nums) != len(set(nums))
# Option 2: O(n log n) time, O(1) extra space
def has_dup_sort(nums):
nums_copy = sorted(nums) # O(n) space -- still!
for i in range(1, len(nums_copy)):
if nums_copy[i] == nums_copy[i-1]:
return True
return False
# Option 3: truly O(1) extra -- sort in-place
def has_dup_inplace(nums):
nums.sort() # modifies original
for i in range(1, len(nums)):
if nums[i] == nums[i-1]: return True
return FalsePlantilla para expresar la complejidad total
Indique siempre la respuesta completa: tiempo y espacio: «O(n) de tiempo y O(1) de espacio adicional». Mencione los equilibrios cuando existan. Eso es lo que distingue a los candidatos con más experiencia.
# Complete complexity example: Merge Intervals
def merge_intervals(intervals):
# Time: O(n log n) for sort + O(n) for merge = O(n log n)
# Space: O(n) for output (could be n/2 to n intervals)
intervals.sort(key=lambda x: x[0]) # O(n log n)
merged = [intervals[0]]
for start, end in intervals[1:]:
if start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return merged
print(merge_intervals([[1,3],[2,6],[8,10],[15,18]]))
# [[1,6],[8,10],[15,18]]Comprobación rápida
Comprobación rápida: veamos cómo ha asimilado las ideas sobre complejidad espacial. Está preparado para esto. ✅
Resumen de la lección
Resumen: el espacio auxiliar se cuenta aparte de la entrada, la recursión utiliza un espacio de pila O(profundidad), y el equilibrio entre tiempo y espacio determina la mayoría de las decisiones de diseño de algoritmos.
Aprende Coding Interview Prep con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 90
- Lecciones
- 360
Preguntas frecuentes
¿La lección «Complejidad espacial y compensaciones» es gratis?
Sí — el texto completo de «Complejidad espacial y compensaciones» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Coding Interview Prep, actualiza a CoddyKit PRO. El curso de Coding Interview Prep incluye 4 lecciones en total.
¿Qué aprenderé en «Complejidad espacial y compensaciones»?
Mida el espacio auxiliar de las pilas de llamadas y las estructuras de datos auxiliares, y reconozca las compensaciones entre tiempo y espacio en la memoización y los algoritmos in-place. Practicas Coding Interview Prep con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Coding Interview Prep?
No se requiere experiencia previa. Coding Interview Prep en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Complejidad espacial y compensaciones»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Coding Interview Prep?
Sí. Cada lección de Coding Interview Prep incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Notación Big-O desde cero
- Análisis de bucles y bucles anidados
- Recursión y método del árbol de recursión
- Complejidad espacial y compensaciones