Array · 3 of 36
Write a program to cyclically rotate an array by one
Turn a merry-go-round one notch: the last rider hops to the front and everyone else moves one seat back.
- Simple way
- time O(n)
room O(n) - Clever way
- time O(n)
room O(1)
The problem, simply
You get an array. Rotate it one step to the right, in a circle: the last item moves to the front, and every other item moves one place to the right.
Change the array itself, using only a little extra room.
A story to remember it
Picture it
Before and after one rotation. 5 jumps from the end to the front, and 1, 2, 3, 4 each move one place right.
- just added
Examples
A normal case
- In
[1, 2, 3, 4, 5]- Out
[5, 1, 2, 3, 4]
5 goes to the front, the rest shift right.
Two items
- In
[9, 8]- Out
[8, 9]
With two items, rotating is the same as swapping.
All the same
- In
[7, 7, 7]- Out
[7, 7, 7]
The items move, but you cannot tell. The code still must not break.
One item
- In
[4]- Out
[4]
The last item is also the first. Nothing changes.
Empty
- In
[]- Out
[]
There is no last item to save. Check the length before reading arr[n - 1].
Way 1: the simple way
Build a new array. Put the last item at index 0, then copy the old item i - 1 into new spot i. Copy it back if the caller expects the same array.
class Solution {
public void rotate(int[] arr) {
int n = arr.length;
if (n <= 1) return;
int[] out = new int[n];
out[0] = arr[n - 1]; // the last item goes first
for (int i = 1; i < n; i++) out[i] = arr[i - 1];
System.arraycopy(out, 0, arr, 0, n); // put the result back
}
}How long it takes: one walk to fill and one to copy back, O(n). Extra room: a second array, O(n).
Way 2: the clever way
Hold one item, then slide from the back.
- Save the last item in
last. - For
ifromn - 1down to 1, copyarr[i - 1]intoarr[i]. - Put
lastintoarr[0].
Going from the back matters. Each copy writes into a spot whose old value was already moved or saved.
Save the last, slide from the back, drop it in front
01 / 06
Save the last item, 5, in last. Its spot is now free to overwrite.
- last
- 5
- checking
- done
- answer
- just added
- ignored
class Solution {
public void rotate(int[] arr) {
int n = arr.length;
if (n <= 1) return; // nothing to rotate
int last = arr[n - 1]; // hold on to the last item
for (int i = n - 1; i > 0; i--) {
arr[i] = arr[i - 1]; // slide right, from the back
}
arr[0] = last; // the saved item goes in front
}
}How long it takes: one walk, O(n). Extra room: one saved number, O(1).
Watch out for
- Read the direction carefully. "Rotate by one" usually means to the right (the last item goes first). Rotating left means the first item goes last: save
arr[0]and slide from the front. - An empty array has no
arr[n - 1]. Return early whenn <= 1.
What interviewers ask next
- Rotate by
ksteps. Doing one stepktimes isO(n k). Instead use three flips: flip the whole array, then flip the firstkitems, then flip the rest. That isO(n)time andO(1)room. Usek % nfirst. - Why do three flips work? Flipping the whole array puts the last
kitems in front, but backwards, and the rest after them, also backwards. Flipping each part fixes their inside order. - Another
O(n)andO(1)method is the juggling method: move items in cycles of stepk, and there aregcd(n, k)cycles. - Rotate a linked list by
k. Join the tail to the head to make a ring, walk to the new tail, and cut there.
Remember this
Grown-up words: the merry-go-round turn is a cyclic rotation, sliding from the back avoids overwriting values, and the three flips for k steps are the reversal algorithm.