Given the head of a linked list, rotate the list to the right by k places.
Example 1:
Input: head = [1,2,3,4,5], k = 2
Output: [4,5,1,2,3]
Example 2:
Input: head = [0,1,2], k = 4
Output: [2,0,1]
Constraints:
The number of nodes in the list is in the range [0, 500].
-100 <= Node.val <= 100
0 <= k <= 2 * 109
Solutions
Solution 1: Fast and Slow Pointers + Link List Concatenation
Thinking
The first idea is to dump the list into an array, rotate, and rebuild. \(n \le 500\) is fine, but \(k\) can be \(2 \times 10^9\), so we cannot rotate one step at a time.
The bottleneck is both the huge \(k\) and locating the new head without random access. Right-rotating \(k\) times equals rotating \(k \bmod n\) times; the new head is the \(k\)-th node from the tail.
A gap of \(k\) between fast and slow pointers puts slow just before the new head when fast reaches the tail, so we never recount \(n-k\). We only rewire a few pointers, in \(O(1)\) extra space.
First, we check whether the number of nodes in the linked list is less than \(2\). If so, we directly return \(head\).
Otherwise, we first count the number of nodes \(n\) in the linked list, and then take the modulus of \(k\) by \(n\) to get the effective value of \(k\).
If the effective value of \(k\) is \(0\), it means that the linked list does not need to be rotated, and we can directly return \(head\).
Otherwise, we use fast and slow pointers, let the fast pointer move \(k\) steps first, and then let the fast and slow pointers move together until the fast pointer moves to the end of the linked list. At this time, the next node of the slow pointer is the new head node of the linked list.
Finally, we concatenate the linked list.
The time complexity is \(O(n)\), where \(n\) is the number of nodes in the linked list. The space complexity is \(O(1)\).
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */funcrotateRight(head*ListNode,kint)*ListNode{ifhead==nil||head.Next==nil{returnhead}cur:=headn:=0forcur!=nil{cur=cur.Nextn++}k%=nifk==0{returnhead}fast,slow:=head,headfori:=0;i<k;i++{fast=fast.Next}forfast.Next!=nil{fast=fast.Nextslow=slow.Next}ans:=slow.Nextslow.Next=nilfast.Next=headreturnans}