Advertisement
Home Data Structure Arrays Cyclically Rotate an Array

Cyclically Rotate an Array

1
Advertisement

Title: Cyclically Rotate an Array

In this guide, you will learn how to cyclically rotate an array in Java by one position to the right. Given an input such as {10, 20, 30, 40, 50}, a single cyclic rotation produces {50, 10, 20, 30, 40} – the last element wraps around to the front, and every other element slides one step to the right.

This classic array manipulation problem shows up often in beginner interviews because it tests whether you can mutate an array in place without clobbering values you still need to read. We will walk through the approach, the full Java program, a step-by-step dry run, worked examples, common mistakes, edge cases, and interview follow-ups.

Understanding the Problem

A cyclic rotation by one position shifts every element one slot to the right, and the element that falls off the right end re-enters at the left end. If the original array is arr with length n, then after the rotation arr[0] holds the old arr[n - 1], and for every other index i in the range 1 to n - 1, arr[i] holds the old arr[i - 1].

The challenge is to do this in place, using only a single extra variable. If you try to shift from left to right, you overwrite values before you ever read them. The trick is to iterate from the right end back toward index 1, so each cell is read before it is overwritten.

Approach

The algorithm has four short steps and runs in linear time with constant extra memory.

  1. Guard against the trivial cases: if the array is null or has fewer than two elements, there is nothing to rotate.
  2. Save the last element arr[n - 1] in a temporary variable last.
  3. Loop i from n - 1 down to 1, and set arr[i] = arr[i - 1]. This slides every element one position to the right without losing any value.
  4. Place the saved last value into arr[0], completing the wrap-around.

Java Program

Here is the complete, compilable Java program. The rotateByOne method mutates the array in place, and main prints the array before and after the rotation.

Java
public class CyclicallyRotateArray {

    public static void rotateByOne(int[] arr) {
        if (arr == null || arr.length <= 1) {
            return;
        }
        int n = arr.length;
        int last = arr[n - 1];
        for (int i = n - 1; i > 0; i--) {
            arr[i] = arr[i - 1];
        }
        arr[0] = last;
    }

    public static void printArray(int[] arr) {
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
            if (i < arr.length - 1) {
                System.out.print(", ");
            }
        }
        System.out.println("]");
    }

    public static void main(String[] args) {
        int[] numbers = {10, 20, 30, 40, 50};
        System.out.print("Original: ");
        printArray(numbers);
        rotateByOne(numbers);
        System.out.print("Rotated:  ");
        printArray(numbers);
    }
}

Running this program prints:

Original: [10, 20, 30, 40, 50]
Rotated: [50, 10, 20, 30, 40]

Explanation of the Program

The rotateByOne method does the real work. The guard clause at the top returns immediately when the input is null or holds zero or one element, because such an array is already its own cyclic rotation. This avoids both NullPointerException and wasted work.

Next, last captures arr[n - 1]. Without this snapshot, the shift loop would overwrite the final element and lose it forever. The loop then walks i from n - 1 down to 1, copying arr[i - 1] into arr[i]. Because we move from the right, each destination cell is written only after its own old value has been copied one step further right.

After the loop finishes, index 0 is a free slot: its original value has already been copied into index 1. The final assignment arr[0] = last drops the saved element into that slot and completes the wrap-around.

The printArray helper formats the array in a readable bracketed form so you can visually confirm the rotation.

Step-by-Step Trace

Let us trace the algorithm on the input [7, 2, 9, 4, 1, 6]. The expected output is [6, 7, 2, 9, 4, 1]. First, last captures 6 (the value at index 5). Then the loop runs for i = 5, 4, 3, 2, 1.

Iterationiarr[i-1]arr[i] (before)arr[i] (after)Array state
15161[7, 2, 9, 4, 1, 1]
24414[7, 2, 9, 4, 4, 1]
33949[7, 2, 9, 9, 4, 1]
42292[7, 2, 2, 9, 4, 1]
51727[7, 7, 2, 9, 4, 1]

After the loop, the final assignment arr[0] = last = 6 gives [6, 7, 2, 9, 4, 1], the rotated array. At the end of each iteration, every index greater than or equal to i holds the correctly shifted value, and the saved last is still safely parked outside the array waiting for its final destination.

Examples

Example 1: A Typical Five-Element Array

The most common case, a small array of distinct integers.

Java
int[] numbers = {1, 2, 3, 4, 5};
rotateByOne(numbers);
// Output: [5, 1, 2, 3, 4]

Example 2: A Single-Element Array

A single-element array is already its own cyclic rotation, so the guard clause returns immediately and the array is unchanged.

Java
int[] numbers = {100};
rotateByOne(numbers);
// Output: [100]

Example 3: An Array With Duplicates

Duplicate values do not change the algorithm. Each slot moves one position to the right, regardless of what it contains.

Java
int[] numbers = {4, 4, 2, 4, 2};
rotateByOne(numbers);
// Output: [2, 4, 4, 2, 4]

Common Mistakes to Avoid

A handful of specific bugs account for most incorrect submissions on this problem. Watch for these before you run your tests.

  • Shifting left to right – looping i from 0 upward and writing arr[i] = arr[i + 1] overwrites every value before you can read it, producing an array full of the second element. Iterate from the right end back toward index 1 instead.
  • Forgetting to save the last element – skipping the last snapshot means arr[n - 1] gets overwritten during the shift, and index 0 ends up holding the wrong value. Always capture arr[n - 1] before the loop runs.
  • Loop lower bound of i >= 0 – continuing to i = 0 reads arr[-1] and throws ArrayIndexOutOfBoundsException. Stop the loop at i > 0 and set arr[0] explicitly after the loop.
  • Returning a new array – allocating new int[n] and copying into it works but uses O(n) extra memory and leaves the caller’s reference unchanged. The expected contract is an in-place mutation of the input array.
  • Rotating by taking the modulus of the length – some learners write arr[(i + 1) % n] = arr[i], which produces the correct final answer only if applied in exactly the right order; otherwise it corrupts the array. Prefer the straightforward right-to-left shift.

Edge Cases to Test

Walk through these inputs before you consider the solution complete. Interviewers love to hear a candidate enumerate boundary cases without being asked.

  • Null array reference
  • Empty array
  • Single-element array
  • Two-element array
  • Array of all identical elements
  • Array with duplicates in non-adjacent positions
  • Array containing Integer.MIN_VALUE or Integer.MAX_VALUE
  • Very large array (hundreds of thousands of elements) for performance

Additional Considerations

The time complexity is O(n) because the loop touches every element exactly once. The space complexity is O(1) because we use a single integer variable last regardless of input size. The in-place mutation preserves the caller’s reference, which is often important when the array is a large data structure shared across the program.

The Integer.MIN_VALUE and Integer.MAX_VALUE edge cases do not stress the algorithm, because the method only copies int values and never performs arithmetic on them. No overflow is possible here, which is a nice property compared to problems that involve summing or multiplying array elements.

If you need to rotate a very large array frequently, consider using a circular buffer and tracking a logical start index instead of physically moving elements on every rotation. That trade-off replaces O(n) work per rotation with O(1) work per rotation at the cost of a small wrapper type.

Interview Follow-up Questions

Once the base solution is correct, interviewers typically probe deeper with variants like these.

  • What if you need to rotate the array by K positions instead of 1? – call the single-step rotation K times for the naive O(n*K) approach, or use the three-reversal trick (reverse the whole array, then the first K elements, then the remaining elements) for O(n) time.
  • What if you need to rotate left instead of right? – mirror the algorithm: save arr[0], shift from left to right (arr[i] = arr[i + 1]), and place the saved value at arr[n - 1].
  • What if the array is actually a linked list? – find the tail, connect it to the head to form a cycle, walk to the new tail (at position n - K - 1), and break the cycle there. This runs in O(n) time without any shifting.
  • What if the input is read-only and you must return the rotation as a new array? – allocate an output of the same length and copy input[(i - 1 + n) % n] into position i, which gives O(n) time and O(n) space with no mutation.
  • What if the array is so large it does not fit in memory? – stream the elements through a one-slot buffer or treat the array as a sequence of chunks on disk, applying the rotation across chunk boundaries with a small overlap region.

Conclusion

Cyclically rotating an array by one position is a short algorithm with a sharp pedagogical edge: the direction of the loop matters, and the single-element snapshot is the piece most beginners forget. Once you internalize the right-to-left shift pattern, you can extend it to rotation by K positions, left rotations, and even linked-list variants without re-learning the core idea.

Try adapting the rotateByOne method to accept a second parameter k and rotate by that many positions, then compare your naive version against the three-reversal approach on a large input to see the complexity difference first-hand. You can learn more about array techniques here: Arrays.