Rotate List
Rotate a singly linked list right by k positions by closing the cycle, advancing, and cutting.
4 min read
linked-list
Problem#
Rotate a singly linked list to the right by k positions.
Examples#
[1,2,3,4,5], k = 2→[4,5,1,2,3][0,1,2], k = 4→[2,0,1]
Constraints#
0 <= n <= 500.
Approach#
(1) Compute length n and find tail. (2) Close the list into a cycle by linking tail to head. (3) Compute new tail at position n - 1 - (k mod n) from head. (4) Cut after the new tail.
Solution#
class Solution {public: ListNode* rotateRight(ListNode* head, int k) { if (!head || !head->next || k == 0) return head; int n = 1; ListNode* tail = head; while (tail->next) { tail = tail->next; ++n; } k %= n; if (k == 0) return head; tail->next = head; ListNode* newTail = head; for (int i = 0; i < n - k - 1; ++i) newTail = newTail->next; ListNode* newHead = newTail->next; newTail->next = nullptr; return newHead; }};func rotateRight(head *ListNode, k int) *ListNode { if head == nil || head.Next == nil || k == 0 { return head } n := 1 tail := head for tail.Next != nil { tail = tail.Next n++ } k %= n if k == 0 { return head } tail.Next = head newTail := head for i := 0; i < n-k-1; i++ { newTail = newTail.Next } newHead := newTail.Next newTail.Next = nil return newHead}from typing import Optional
class Solution: def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]: if not head or not head.next or k == 0: return head n = 1 tail = head while tail.next: tail = tail.next n += 1 k %= n if k == 0: return head tail.next = head new_tail = head for _ in range(n - k - 1): new_tail = new_tail.next new_head = new_tail.next new_tail.next = None return new_headfunction rotateRight(head, k) { if (!head || !head.next || k === 0) return head; let n = 1; let tail = head; while (tail.next) { tail = tail.next; n++; } k %= n; if (k === 0) return head; tail.next = head; let newTail = head; for (let i = 0; i < n - k - 1; i++) { newTail = newTail.next; } const newHead = newTail.next; newTail.next = null; return newHead;}class Solution { public ListNode rotateRight(ListNode head, int k) { if (head == null || head.next == null || k == 0) return head; int n = 1; ListNode tail = head; while (tail.next != null) { tail = tail.next; n++; } k %= n; if (k == 0) return head; tail.next = head; ListNode newTail = head; for (int i = 0; i < n - k - 1; i++) newTail = newTail.next; ListNode newHead = newTail.next; newTail.next = null; return newHead; }}function rotateRight(head: ListNode | null, k: number): ListNode | null { if (head === null || head.next === null || k === 0) return head; let n = 1; let tail: ListNode = head; while (tail.next !== null) { tail = tail.next; n++; } k %= n; if (k === 0) return head; tail.next = head; let newTail: ListNode = head; for (let i = 0; i < n - k - 1; i++) { newTail = newTail.next!; } const newHead: ListNode | null = newTail.next; newTail.next = null; return newHead;}Editorial#
Closing into a cycle simplifies the “what’s the new head?” question to a single arithmetic step. After cycling, walking n - k - 1 from head lands on the last node of the rotated list; its next is the new head. Cutting there terminates the list.
Complexity#
- Time: O(n).
- Space: O(1).
Concept revision#
Related#