Operaciones in-place
Cómo modificar un arreglo sin crear uno nuevo. La técnica detrás de la mayoría de problemas O(1) en espacio.
4 min de lectura
"In-place" significa modificar la estructura original sin asignar memoria proporcional al input. Es la base de muchas optimizaciones de espacio, y es lo que te van a pedir cuando un problema diga "resuelve sin usar memoria extra" o "O(1) espacio adicional".
El swap como primitivo
La operación atómica de in-place es el swap: intercambiar dos elementos sin variables auxiliares (más allá de una temporal).
arr[i], arr[j] = arr[j], arr[i]
En JavaScript moderno también funciona con destructuring:
[arr[i], arr[j]] = [arr[j], arr[i]];
O con variable temporal:
const tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
Swap es O(1) tiempo y O(1) espacio. Casi todo algoritmo in-place se reduce a una secuencia de swaps.
Patrones in-place clásicos
1. Revertir un arreglo (dos punteros)
def revertir(arr):
izq, der = 0, len(arr) - 1
while izq < der:
arr[izq], arr[der] = arr[der], arr[izq]
izq += 1
der -= 1
Los punteros se acercan al medio. Cada paso swappa una posición. O(n) tiempo, O(1) espacio.
2. Mover ceros al final
Problema clásico: dado un arreglo, mover todos los ceros al final manteniendo el orden relativo del resto, sin crear arreglo nuevo.
def mover_ceros(arr):
siguiente = 0
for i in range(len(arr)):
if arr[i] != 0:
arr[siguiente], arr[i] = arr[i], arr[siguiente]
siguiente += 1
siguiente marca dónde va el próximo no-cero. Una sola pasada. O(n) tiempo, O(1) espacio.
3. Eliminar duplicados en arreglo ordenado
Dado un arreglo ordenado, deja solo elementos únicos al principio y devuelve la nueva longitud.
def eliminar_duplicados(arr):
if not arr:
return 0
escribir = 1
for leer in range(1, len(arr)):
if arr[leer] != arr[leer - 1]:
arr[escribir] = arr[leer]
escribir += 1
return escribir
Dos punteros: uno lee, uno escribe. Cuando el lector encuentra un valor nuevo, lo copia a la posición de escribir. O(n) tiempo, O(1) espacio.
4. Rotar un arreglo k posiciones
Problema clásico: rotar [1,2,3,4,5,6,7] 3 posiciones a la derecha → [5,6,7,1,2,3,4].
Truco de los tres reversos:
def rotar(arr, k):
n = len(arr)
k = k % n
# 1. Revertir todo
revertir(arr, 0, n - 1)
# 2. Revertir los primeros k
revertir(arr, 0, k - 1)
# 3. Revertir el resto
revertir(arr, k, n - 1)
def revertir(arr, i, j):
while i < j:
arr[i], arr[j] = arr[j], arr[i]
i += 1
j -= 1
Tres pasadas pero todas O(n). Total: O(n) tiempo, O(1) espacio.
La trampa: in-place no siempre es óptimo
Hacer todo in-place puede complicar el código sin ganancia real. Si el arreglo tiene 100 elementos, gastar 100 elementos más de memoria no cambia nada. Si tiene 100 millones, sí importa.
Cuándo conviene in-place:
- El input es grande (millones+).
- El sistema tiene memoria limitada.
- El problema lo pide explícitamente.
Cuándo NO conviene:
- El input es chico y la legibilidad importa más.
- La versión in-place introduce bugs sutiles (índices, swap parcial).
- En entrevista, si la versión no-in-place es claramente correcta y la in-place no, presenta la primera y mencioná la segunda como mejora.
Errores típicos en in-place
Iterar y modificar al mismo tiempo
Si modificas un arreglo mientras lo recorres, puedes saltarte elementos o procesar el mismo dos veces.
# MAL: skip de elementos
for i in range(len(arr)):
if arr[i] == 0:
arr.pop(i) # los siguientes se mueven a la izquierda
Después del pop, el siguiente elemento ahora está en la posición i, pero el loop avanza a i+1. Te lo salteas.
Solución 1: iterar de derecha a izquierda.
for i in range(len(arr) - 1, -1, -1):
if arr[i] == 0:
arr.pop(i)
Solución 2: usar dos punteros y no eliminar, sobrescribir.
Mutar parámetros y devolver el mismo arreglo
Si la función modifica arr y devuelve arr, el código que llama puede confundirse: ¿modifiqué el original o trabajo con uno nuevo?
def revertir(arr):
arr.reverse()
return arr
original = [1, 2, 3]
nuevo = revertir(original)
# Sorpresa: original también está revertido
Si tu función es in-place, deja clara la convención: o no devuelvas nada (la mutación es el resultado), o documentalo explícitamente.
En resumen
In-place es una técnica de optimización de memoria, no una bala de plata. Si te lo piden explícitamente, usalo. Si no, balanceá legibilidad vs eficiencia según el contexto. Y siempre que modifiques al iterar, piensa dos veces.
Inicia sesión para guardar el progreso de esta lección.