DEV Community

DevCorner2
DevCorner2

Posted on

πŸŒ€ Circular Array Problems β€” The Ultimate Interview Guide

Circular arrays show up frequently in coding interviews because they test your ability to handle wraparound conditions, indexing with modulo, and apply DSA patterns (stacks, sliding windows, greedy, etc.).

This blog compiles the most asked circular array problems, with explanations and Java implementations.


πŸ”Ή 1. Next Greater Element in a Circular Array

Problem: For each element, find the next greater element in circular order. If none exists, return -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;
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Monotonic stack.
βœ… Time: O(n).


πŸ”Ή 2. Gas Station (Circular Tour Problem)

Problem: Given gas at each station and cost to travel, find if you can complete a full circular tour.

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;
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Greedy scan.
βœ… Time: O(n).


πŸ”Ή 3. Maximum Sum Circular Subarray

Problem: Find maximum subarray sum in a circular array.

public int maxSubarraySumCircular(int[] nums) {
    int total = 0, maxSum = nums[0], curMax = 0, minSum = nums[0], curMin = 0;
    for (int n : nums) {
        curMax = Math.max(curMax + n, n);
        maxSum = Math.max(maxSum, curMax);
        curMin = Math.min(curMin + n, n);
        minSum = Math.min(minSum, curMin);
        total += n;
    }
    return maxSum > 0 ? Math.max(maxSum, total - minSum) : maxSum;
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Kadane’s Algorithm (max + min).
βœ… Time: O(n).


πŸ”Ή 4. Rotate Array (Circular Shift)

Problem: Rotate an array by k steps to the right.

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 temp = nums[l];
        nums[l++] = nums[r];
        nums[r--] = temp;
    }
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Reverse trick.
βœ… Time: O(n).


πŸ”Ή 5. Circular Sliding Window Maximum

Problem: Given a circular array and window size k, return max in each window.

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;
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Deque-based sliding window.
βœ… Time: O(n).


πŸ”Ή 6. Josephus Problem (Circular Elimination)

Problem: Eliminate every k-th person until one remains.

public int josephus(int n, int k) {
    if (n == 1) return 0;
    return (josephus(n - 1, k) + k) % n;
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Recursion / DP.
βœ… Time: O(n).


πŸ”Ή 7. Circular Array Loop Detection

Problem: Given jumps in a circular array, check if a cycle exists.

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 next = ((i + nums[i]) % n + n) % n;
    if (next == i) return -1; 
    return next;
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Floyd’s cycle detection.
βœ… Time: O(n).


πŸ”Ή 8. Shortest Distance in Circular Array

Problem: Find shortest distance between two indices.

public int shortestCircularDistance(int n, int i, int j) {
    int diff = Math.abs(i - j);
    return Math.min(diff, n - diff);
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Math formula.
βœ… Time: O(1).


πŸ”Ή 9. Circular Queue / Deque Design

Problem: Implement a circular deque with insert/delete operations.

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; }
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pattern: Modular arithmetic.
βœ… Time: O(1) per operation.


🧠 Key Patterns

  1. Modulo indexing (i % n) β†’ core trick for wraparound.
  2. Extended array trick (concatenate with itself) β†’ useful for sliding windows.
  3. Kadane’s Algorithm β†’ max/min subarray in circular arrays.
  4. Greedy scanning β†’ gas station.
  5. Cycle detection (Floyd’s algo) β†’ circular jumps.

βœ… Final Thoughts

  • Circular problems aren’t just about arrays β€” they show up in scheduling, networking, OS (round robin), and system design.
  • Mastering these 8–10 problems covers 90% of interview questions in this domain.
  • The secret sauce: always think in modular arithmetic and leverage existing patterns (stack, deque, DP, greedy).

Top comments (0)