Intuition
Rotating right by k just moves the last k nodes to the front — one cut, one splice. Close the list into a ring, walk to the new tail (position n − k%n − 1), and cut there. No node-by-node shuffling.
Rotation is really "cut the list at a new place". Closing it into a ring first means you never juggle two loose ends — you just walk to the new tail and break there. Whenever a rotation problem gives you a linear structure, ask whether making it circular removes the special cases; it usually does.
Approach
Measure and normalize k
Walk once to get length n; k %= n since rotating by n is a no-op. If k becomes 0, return as-is.
Make it a ring
Point the old tail at the head. Now rotation is purely a question of where to cut.
Cut at the new tail
The new tail sits n − k − 1 steps from the old head. New head is its next; set tail.next = None.
Solution & live demo
Common pitfalls
Not reducing k modulo the length
for _ in range(k):
# rotate one stepk %= n if k == 0: return head
k can far exceed the list length — rotating a 3-node list 2,000,000 times is the same as rotating it twice. Without the modulo the loop runs k times, timing out on the exact inputs the problem is testing.
Counting the length off by one
n, tail = 0, head
while tail.next:
tail = tail.next; n += 1n, tail = 1, head
while tail.next:
tail = tail.next; n += 1The loop advances once per edge, not per node, so starting at 0 undercounts by one. That makes k % n wrong and the cut lands one position off.
Walking n - k steps to find the new tail
for _ in range(n - k):
new_tail = new_tail.nextfor _ in range(n - k - 1):
new_tail = new_tail.nextStarting from head, taking n - k steps lands on the new head, one past the node you need to cut after. The new tail sits at index n - k - 1.
Edge cases
k %= n reduces both to the trivial case — return head unchanged.
Early return; nothing to rotate.