Linked Lists · Linked List Fundamentals

Linked List Rotation

Rotating a list by temporarily joining tail to head (making it circular), then breaking the circle at the correct new tail - avoiding any node-by-node value shifting.

  • 5 min read
  • 10 practice questions
  • 2 graded problems
On this page
  1. Description
  2. The approach
  3. A second flavor: rotating the other direction
  4. Where you'll see it
  5. Which tool for which job?
  6. Common mistakes
  7. Check yourself
  8. Key takeaways
  9. Quick revise
  10. Practice

Description

Rotating a linked list by k places moves the last k nodes to the front, without moving any values. Join the tail to the head to make a ring, walk to the node that should become the new tail, and cut the ring after it. The whole skill is getting three numbers right: the length, k modulo the length, and how far from the head the cut falls.

We'll go from simple to more technical:

  1. The pattern: measure, close the ring, cut at the new tail.
  2. A second flavor: rotating left with the same steps and a different cut point.
  3. Where "move the start, not the data" shows up (ring buffers).
  4. The mistakes that rotate by the wrong amount or the wrong way.

The approach

Rotating doesn't need to move any values. Only the node where the list starts changes. So link the tail back to the head, making a ring. Then pick the node that should be the new tail, make the node after it the new head, and cut the ring there.

Rotating 6 -> 2 -> 9 -> 4 -> 7 right by 2:

StepWhat happens
1. Measurethe length is 5, and the tail is 7
2. Reduce kshift = 2 % 5 = 2
3. Close the ring7 now points back to 6
4. Find the new tail5 - 2 - 1 = 2 steps from 6 lands on 9
5. Cutthe new head is 4, and 9 now points to null

The result is 4 -> 7 -> 6 -> 2 -> 9: the last two nodes moved to the front. Rotating by 7 gives the same list, because 7 % 5 is also 2.

Java

if (head == null || head.next == null) return head;   // nothing to rotate
int length = 1;
ListNode tail = head;
while (tail.next != null) { tail = tail.next; length++; }

int shift = k % length;              // rotating by a multiple of the length is a no-op
if (shift == 0) return head;

tail.next = head;                     // temporarily circular
int stepsToNewTail = length - shift - 1;
ListNode newTail = head;
for (int i = 0; i < stepsToNewTail; i++) newTail = newTail.next;
ListNode newHead = newTail.next;
newTail.next = null;                  // break the circle at the new end
return newHead;

Python

def rotate_right(head: ListNode | None, k: int) -> ListNode | None:
    if head is None or head.next is None:
        return head                          # nothing to rotate
    length = 1
    tail = head
    while tail.next is not None:
        tail = tail.next
        length += 1

    shift = k % length                       # rotating by a multiple of the length is a no-op
    if shift == 0:
        return head

    tail.next = head                         # temporarily circular
    new_tail = head
    for _ in range(length - shift - 1):
        new_tail = new_tail.next
    new_head = new_tail.next
    new_tail.next = None                     # break the circle at the new end
    return new_head

k % length isn't just a speed-up. Rotating by the full length gives back the same list. And the cut formula assumes the shift is between 0 and length - 1. With a raw k bigger than the length, length - k - 1 goes negative and the cut lands in the wrong place.

A second flavor: rotating the other direction

Rotating left by k moves the first k nodes to the end. The ring and the cut are the same. Only the new tail changes: it's shift - 1 steps from the head, counted from the front. Left by 2, the list above becomes 9 -> 4 -> 7 -> 6 -> 2.

Java

tail.next = head;                          // temporarily circular, same as before
int stepsToNewTail = shift - 1;             // LEFT rotation: measured from the FRONT, not the back
ListNode newTail = head;
for (int i = 0; i < stepsToNewTail; i++) newTail = newTail.next;
ListNode newHead = newTail.next;
newTail.next = null;
return newHead;

Python

tail.next = head                             # temporarily circular, same as before
new_tail = head
for _ in range(shift - 1):                   # LEFT rotation: measured from the FRONT, not the back
    new_tail = new_tail.next
new_head = new_tail.next
new_tail.next = None

Mixing up the two formulas doesn't crash or make garbage. It gives a perfectly valid rotation in the other direction, so test with a direction you can check by hand.

Where you'll see it

A ring buffer works on the same idea. The data never moves; only the index where the sequence starts changes. Logs and queues with a fixed amount of memory are often built this way.

Which tool for which job?

You needUse
Rotate a linked list right by kring, then cut n - k % n - 1 steps from the head
Rotate left by kthe same, cut k % n - 1 steps from the head (or right by n - k % n)
Rotate a Java listCollections.rotate(list, k) (negative = left)
Rotate a Python sequence oftencollections.deque.rotate(k)
A queue whose "start" moves constantlya ring buffer with a head index

Common mistakes

MistakeWhat happensDo this instead
No k % nhuge k means huge loops, or a negative step countreduce k first
Cutting k steps from the head for a right rotationrotates the other waythe new tail is n - k - 1 steps in
Leaving the ring closed when k % n == 0an endless cyclereturn early, before closing it
No check for empty or one-node listsnull dereferencereturn them unchanged
Copying values into an array to rotateO(n) extra spacerelink two pointers

Check yourself

Try to answer before opening each one - recalling beats re-reading.

1. Why does shift = k % length matter beyond saving work?

Show answer

The cut formula assumes the shift is between 0 and length - 1. With a k bigger than the length, length - k - 1 goes negative and the cut lands in the wrong place. Rotating by a multiple of the length changes nothing, so the remainder is all that counts.

2. For a right rotation, why is the new tail length - shift - 1 steps from the head, not shift steps?

Show answer

The shift says how many nodes move from the back to the front. The new tail is the last node that stays put, and length - shift nodes stay put. So it's length - shift - 1 steps from the head. shift steps would measure from the wrong end.

3. A left rotation uses the right rotation's formula by mistake. What does it return?

Show answer

A valid, well-formed rotation in the wrong direction: the right rotation's answer. Nothing crashes. The cut-point formula is the only thing that decides the direction.

Key takeaways

  • Rotation moves where the list starts, not the values. A temporary ring turns it into choosing where to cut.
  • Reduce k with k % length first, or the cut lands in the wrong place.
  • Right rotation cuts length - shift - 1 steps from the head. Left rotation cuts shift - 1 steps from the head.
  • Every bug here gives a believable list, so check the direction by hand.
  • Relinking two pointers needs O(1) space. Copying the values into an array needs O(n).

Quick revise

The whole skill on one page, for the night before an interview.

Everything from the lesson and the deep dive on one page. Skim it before practice or an interview, and open the full lesson for anything that doesn't ring a bell.

Pick the tool

You needUse
Right by kring, cut n - k % n - 1 from the head
Left by kright by n - k % n
Java listCollections.rotate
Pythondeque.rotate
Frequent rotationsa head index

Snippets worth knowing by heart

Java

if (head == null || head.next == null) return head;
int n = 1; ListNode tail = head;
while (tail.next != null) { tail = tail.next; n++; }
k %= n;
if (k == 0) return head;                 // before closing the ring
tail.next = head;                        // ring
ListNode newTail = head;
for (int i = 0; i < n - k - 1; i++) newTail = newTail.next;
ListNode newHead = newTail.next;
newTail.next = null;                     // cut
return newHead;

Python

from collections import deque
d = deque([1, 2, 3, 4, 5])
d.rotate(2)        # right: deque([4, 5, 1, 2, 3])
d.rotate(-2)       # left, back to deque([1, 2, 3, 4, 5])

The traps

  • No k % n: a huge k means a huge loop. Reduce k first.
  • The wrong cut distance: cutting k steps in rotates the wrong way. The new tail is n - k - 1 steps in.
  • A ring left closed when k % n == 0: the list becomes an endless cycle. Return early, before closing it.
  • Empty or single-node lists: the walk dereferences null. Return them unchanged.
  • Copying to an array: rotating values costs O(n) extra space. Relink two pointers.

Staff-level points, one line each

  • k = 10^12 + 2 on 5 nodes: 7 pointer steps.
  • Left by k = right by n - k % n.
  • Collections.rotate: 2 and 12 gave the same; -2 rotates left.
  • deque.rotate is O(k), negative = left.
  • Frequent rotation: a ring buffer's head index, O(1).

Say it in an interview

  • "I measure the length, reduce k, close the ring, and cut after the new tail."
  • "The new tail is n - k - 1 steps from the old head."
  • "It's O(n) time and O(1) space, whatever k is."
  • "If we rotated often, I'd keep an array and move a head index."

Practice

This skill comes with 10 multiple-choice questions that tell you which misconception a wrong answer reveals and 2 graded problems. Your answers are graded and your mastery is tracked, so you'll know when the skill holds up. Running code and saving progress need a free account.

Practice Linked List Rotation free

Rotate a LinkedList

MediumProCoding problemJava · Python

Move the last k nodes of a linked list to the front, keeping their order, and return the new head. That is a rotation to the right by k places.

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Rotate a LinkedList Left

MediumProCoding problemJava · Python

Given the head of a linked list, rotate the list to the left by k places (move the first k nodes to the end, instead of moving the last k nodes to the front).

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Practice Linked List Rotation free

No card needed. Lessons, practice questions and easy problems are free forever.

Free plan, no card · 7-day Pro trial · Cancel anytime