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:
[0, 500].-100 <= Node.val <= 1000 <= k <= 2 * 109The Rotate List problem asks you to rotate a singly linked list to the right by k positions. A straightforward idea is to repeatedly move the last node to the front, but this becomes inefficient for large k. A more optimal strategy relies on understanding the length of the list and using a two-pointer technique.
First, traverse the list to compute its length and identify the tail node. Since rotating by the list length results in the same list, reduce the rotations using k % length. Then locate the new tail by moving length - k - 1 steps from the head. The node after this becomes the new head. By temporarily connecting the tail to the head, you can treat the list as circular and then break the link at the correct position.
This approach efficiently performs the rotation in O(n) time with O(1) extra space.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Length Calculation + Two Pointer Rotation | O(n) | O(1) |
Greg Hogg
This approach involves converting the linked list into a circular list and then breaking it at the correct point to achieve the required rotation.
By making the linked list a circular one, you can easily traverse k nodes from the end to set the new head and make necessary detachments.
Time Complexity: O(n) because we pass through the list twice, once to find the length and once to find the new head.
Space Complexity: O(1) since we only use a constant amount of extra space.
1function ListNode(val) {
2 this.val = val;
3 this.next = null;
4}
5
6var rotateRight = function(head, k) {
7 if (!head || k === 0) return head;
8 let length = 1;
9 let current = head;
10 while (current.next) {
11 current = current.next;
12 length++;
13 }
14 current.next = head; // make it circular
15 k %= length;
16 for (let i = 0; i < length - k; i++) {
17 current = current.next;
18 }
19 head = current.next;
20 current.next = null;
21
22 return head;
23};
24
25// Example usage
26let head = new ListNode(1);
27head.next = new ListNode(2);
28head.next.next = new ListNode(3);
29head.next.next.next = new ListNode(4);
30head.next.next.next.next = new ListNode(5);
31let newHead = rotateRight(head, 2);
32let current = newHead;
33while (current != null) {
34 console.log(current.val);
35 current = current.next;
36}This JavaScript solution follows the same approach. Consistently traverse to create a circular linked list, utilize k modulo length, and break the list at the appropriate point to achieve the desired rotation.
In this approach, we utilize a two-pointer technique. We advance one pointer ahead by k nodes and then move another pointer from the start concurrently until the first pointer reaches the list's end. This way, the second pointer will eventually land on the node that will become the new tail.
Time Complexity: O(n) because it requires traversal for counting.
Space Complexity: O(1) as no extra space is used.
1public class ListNode {
2 public int val;
3 public ListNode next;
4 public ListNode(int val = 0, ListNode next = null) {
this.val = val;
this.next = next;
}
}
public class Solution {
public ListNode RotateRight(ListNode head, int k) {
if (head == null || k == 0) return head;
ListNode fast = head, slow = head;
int length = 1;
while (fast.next != null) {
fast = fast.next;
length++;
}
fast.next = head; // form circular
k %= length;
for (int i = 0; i < length - k; i++) {
slow = slow.next;
fast = fast.next;
}
head = slow.next;
fast.next = null;
return head;
}
public static void Main() {
ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
Solution sol = new Solution();
ListNode newHead = sol.RotateRight(head, 2);
ListNode curr = newHead;
while (curr != null) {
Console.Write(curr.val + " ");
curr = curr.next;
}
}
}
Watch expert explanations and walkthroughs
Practice problems asked by these companies to ace your technical interviews.
Explore More ProblemsJot down your thoughts, approach, and key learnings
If k is larger than the length of the list, rotating more than the list size results in repeated patterns. Using k % length eliminates unnecessary rotations and ensures we only perform the minimum required shifts.
Yes, linked list manipulation problems like Rotate List are common in FAANG and other top tech company interviews. They test understanding of pointers, list traversal, and edge case handling.
The optimal approach first computes the length of the linked list and reduces k using k % length. Then it finds the new tail using a pointer traversal and reconnects the list accordingly. This method rotates the list in O(n) time and O(1) space.
The problem uses a singly linked list as the main data structure. Efficient traversal and pointer manipulation are key to changing node connections without creating extra structures.
In this C# solution, the logic is similar to the previous languages. After determining the length and connecting the end, the fast and slow pointers identify the correct division point. This method makes efficient use of mid-list pointer adjustments to achieve rotation.