Guía definitiva de problemas con arrays circulares para entrevistas técnicas. Los arrays circulares aparecen en entrevistas porque obligan a manejar condiciones de vuelta al inicio wraparound, a indexar con módulo y a aplicar patrones de DSA como pilas, ventanas deslizantes, greedy, entre otros. Aquí encontrarás los problemas más preguntados, con explicación resumida y sus implementaciones en Java, además de consejos prácticos para no caer en trampas típicas.
1. Siguiente elemento mayor en un array circular
Problema: para cada elemento, encuentra el siguiente mayor en orden circular. Si no existe, devuelve -1.
import java.util.*; public int[] nextGreaterElements(int[] nums) { int n = nums.length; int[] res = new int[n]; Arrays.fill(res, -1); Deque<Integer> stack = new ArrayDeque<>(); for (int i = 0; i < 2 * n; i++) { int num = nums[i % n]; while (!stack.isEmpty() && nums[stack.peek()] < num) { res[stack.pop()] = num; } if (i < n) stack.push(i); } return res; }
Patrón: pila monótona. Complejidad temporal: O(n).
2. Gasolinera recorrido circular
Problema: dado el gas disponible en cada estación y el coste de viajar a la siguiente, determina si puedes completar la vuelta y desde qué índice empezar.
public int canCompleteCircuit(int[] gas, int[] cost) { int total = 0, tank = 0, start = 0; for (int i = 0; i < gas.length; i++) { int diff = gas[i] - cost[i]; total += diff; tank += diff; if (tank < 0) { start = i + 1; tank = 0; } } return total < 0 ? -1 : start; }
Patrón: recorrido greedy. Complejidad temporal: O(n).
3. Máxima suma de subarray circular
Problema: halla la suma máxima de un subarray en un array circular.
public int maxSubarraySumCircular(int[] nums) { int total = 0, maxSum = nums[0], curMax = 0, minSum = nums[0], curMin = 0; for (int v : nums) { curMax = Math.max(curMax + v, v); maxSum = Math.max(maxSum, curMax); curMin = Math.min(curMin + v, v); minSum = Math.min(minSum, curMin); total += v; } return maxSum > 0 ? Math.max(maxSum, total - minSum) : maxSum; }
Patrón: algoritmo de Kadane para máximo y mínimo. Complejidad temporal: O(n).
4. Rotación circular de un array
Problema: rota un array k pasos a la derecha.
public void rotate(int[] nums, int k) { int n = nums.length; k %= n; reverse(nums, 0, n - 1); reverse(nums, 0, k - 1); reverse(nums, k, n - 1); } private void reverse(int[] nums, int l, int r) { while (l < r) { int t = nums[l]; nums[l++] = nums[r]; nums[r--] = t; } }
Patrón: truco de tres inversiones. Complejidad temporal: O(n).
5. Máximos de ventana deslizante circular
Problema: dado un array circular y una ventana de tamaño k, devuelve el máximo de cada ventana.
import java.util.*; public int[] circularSlidingWindowMax(int[] nums, int k) { int n = nums.length; int[] extended = new int[2 * n]; System.arraycopy(nums, 0, extended, 0, n); System.arraycopy(nums, 0, extended, n, n); Deque<Integer> deque = new ArrayDeque<>(); int[] res = new int[n]; for (int i = 0; i < 2 * n; i++) { while (!deque.isEmpty() && extended[deque.peekLast()] <= extended[i]) { deque.pollLast(); } deque.addLast(i); if (deque.peekFirst() <= i - k) { deque.pollFirst(); } if (i >= k - 1 && i < n + k - 1) { res[i - k + 1] = extended[deque.peekFirst()]; } } return res; }
Patrón: deque para ventana deslizante. Complejidad temporal: O(n).
6. Problema de Josephus eliminación circular
Problema: se elimina a cada k-ésima persona hasta que queda una.
public int josephus(int n, int k) { if (n == 1) return 0; return (josephus(n - 1, k) + k) % n; }
Patrón: recursión y relación de recurrencia. Complejidad temporal: O(n).
7. Detección de bucle en array circular
Problema: dado un array de saltos, determina si existe un ciclo que respete la dirección del movimiento.
public boolean circularArrayLoop(int[] nums) { int n = nums.length; for (int i = 0; i < n; i++) { int slow = i, fast = i; boolean forward = nums[i] > 0; while (true) { slow = next(nums, forward, slow); if (slow == -1) break; fast = next(nums, forward, fast); if (fast == -1) break; fast = next(nums, forward, fast); if (fast == -1) break; if (slow == fast) return true; } } return false; } private int next(int[] nums, boolean forward, int i) { boolean dir = nums[i] > 0; if (dir != forward) return -1; int n = nums.length; int nx = ((i + nums[i]) % n + n) % n; if (nx == i) return -1; return nx; }
Patrón: detección de ciclos de Floyd tortuga y liebre. Complejidad temporal: O(n).
8. Distancia mínima en un círculo
Problema: calcula la distancia más corta entre dos índices en una circunferencia de tamaño n.
public int shortestCircularDistance(int n, int i, int j) { int diff = Math.abs(i - j); return Math.min(diff, n - diff); }
Patrón: fórmula matemática. Complejidad temporal: O(1).
9. Diseño de cola doblemente terminada circular deque
Problema: implementa un deque circular con inserciones y borrados en ambos extremos en O(1).
class MyCircularDeque { private int[] data; private int front, rear, size, capacity; public MyCircularDeque(int k) { data = new int[k]; capacity = k; front = 0; rear = -1; size = 0; } public boolean insertFront(int value) { if (isFull()) return false; front = (front - 1 + capacity) % capacity; data[front] = value; size++; if (rear == -1) rear = front; return true; } public boolean insertLast(int value) { if (isFull()) return false; rear = (rear + 1) % capacity; data[rear] = value; size++; return true; } public boolean deleteFront() { if (isEmpty()) return false; front = (front + 1) % capacity; size--; return true; } public boolean deleteLast() { if (isEmpty()) return false; rear = (rear - 1 + capacity) % capacity; size--; return true; } public boolean isFull() { return size == capacity; } public boolean isEmpty() { return size == 0; } }
Patrón: aritmética modular. Complejidad temporal: O(1) por operación.
Patrones clave para arrays circulares
- Indexación con módulo i % n para cerrar el círculo. - Duplicar el array concatenándolo consigo mismo para ventanas deslizantes. - Algoritmo de Kadane para máximo y mínimo en variante circular. - Greedy lineal para problemas de viabilidad como gasolinera. - Detección de ciclos de Floyd en saltos circulares.
Consejos finales
Los problemas circulares no son exclusivos de arrays; aparecen en planificación de tareas, redes, sistemas operativos rondas robin y diseño de sistemas. Dominar 8 a 10 de estos patrones cubre la mayoría de preguntas de entrevista. La clave está en pensar siempre en aritmética modular, aprovechar estructuras como pila y deque, y reconocer cuándo aplicar greedy o DP.
Sobre Q2BSTUDIO y cómo podemos ayudarte
En Q2BSTUDIO aceleramos tu adopción de buenas prácticas de ingeniería y trasladamos estas ideas a productos reales mediante software a medida y aplicaciones a medida de alta calidad. Si buscas un socio de desarrollo, explora nuestro enfoque en aplicaciones a medida para backend, frontend y multiplataforma.
También aplicamos inteligencia artificial e IA para empresas con agentes IA y analítica avanzada, reforzando la ciberseguridad y cumpliendo estándares en servicios cloud AWS y Azure, además de montar soluciones de servicios inteligencia de negocio y power bi. Conoce cómo llevamos tus modelos y casos de uso de IA de prototipo a producción en nuestra área de inteligencia artificial.
Palabras clave recomendadas para mejorar el posicionamiento: aplicaciones a medida, software a medida, inteligencia artificial, ciberseguridad, servicios cloud aws y azure, servicios inteligencia de negocio, ia para empresas, agentes IA, power bi.