Knowledge Guide
HomeDSACompany Practice

medium Rotate List

Problem Statement

Given the head of a linked list and integer k, rotate the list to the right by k places.

Examples

  1. Example 1:

    • Input: head = [7, 13, 1], k = 2
    • Expected Output: [13, 1, 7]
    • Justification: The list [7, 13, 1] when rotated by 2 positions to the right, the last two elements (13 and 1) move to the front, resulting in [13, 1, 7].
  2. Example 2:

    • Input: head = [3, 5, 9, 12], k = 1
    • Expected Output: [12, 3, 5, 9]
    • Justification: Rotating the list [3, 5, 9, 12] by 1 position to the right, the last element (12) moves to the front of the list, giving us [12, 3, 5, 9].
  3. Example 3:

    • Input: head = [22, 4, 10, 15, 29], k = 7
    • Expected Output: [15, 29, 22, 4, 10]
    • Justification: Since k is greater than the length of the list (which is 5), we effectively need to rotate the list by k % length = 2 positions to the right. Thus, the last two elements (29 and 15) move to the front, resulting in [15, 29, 22, 4, 10].

Try it yourself

Try solving this question here:

✅ Solution Rotate List

Problem Statement

Given the head of a linked list and integer k, rotate the list to the right by k places.

Examples

  1. Example 1:

    • Input: head = [7, 13, 1], k = 2
    • Expected Output: [13, 1, 7]
    • Justification: The list [7, 13, 1] when rotated by 2 positions to the right, the last two elements (13 and 1) move to the front, resulting in [13, 1, 7].
  2. Example 2:

    • Input: head = [3, 5, 9, 12], k = 1
    • Expected Output: [12, 3, 5, 9]
    • Justification: Rotating the list [3, 5, 9, 12] by 1 position to the right, the last element (12) moves to the front of the list, giving us [12, 3, 5, 9].
  3. Example 3:

    • Input: head = [22, 4, 10, 15, 29], k = 7
    • Expected Output: [15, 29, 22, 4, 10]
    • Justification: Since k is greater than the length of the list (which is 5), we effectively need to rotate the list by k % length = 2 positions to the right. Thus, the last two elements (29 and 15) move to the front, resulting in [15, 29, 22, 4, 10].

Solution

To solve this problem, we will first determine the length of the linked list as it is crucial for handling cases where k is greater than the length of the list. By finding the length, we can normalize k to ensure we do not perform unnecessary rotations. The essence of the approach involves connecting the last node of the list to the first node, forming a circular linked list, then breaking this circle at the correct position to form the rotated list. This approach is effective because it allows us to directly access the new head of the list after rotation with minimal computations, ensuring efficiency in terms of both time and space.

To implement this solution, we will follow these steps: calculate the length of the list, normalize k, find the new head of the rotated list, and adjust the next pointers of the nodes to reflect the rotation. This method is chosen for its direct approach to achieving the desired list configuration without needing to individually shift elements or use additional data structures, making it an optimized solution for the problem.

Step-by-step Algorithm

  1. Check Base Conditions: If the list is empty (head == null), consists of a single element (head.next == null), or no rotation is requested (k == 0), simply return the head of the list as it is.

  2. Calculate List Length and Form a Circular List:

    • Initialize a variable length to 1 (since we are starting with at least one node).
    • Traverse the list with a pointer (say current) to find the tail node (where current.next == null) and count the nodes to find the total length of the list.
    • Once the tail node is found, form a circular list by pointing current.next to the head (current.next = head).
  3. Normalize the Rotation:

    • Since rotating the list by its length brings it back to the original position, normalize k by taking the remainder of k divided by the length (k = k % length).
    • If k is 0 after normalization (meaning the rotation count is a multiple of the list's length), break the circular link formed earlier and return the head (list remains unchanged).
  4. Find the New Head and Tail:

    • Calculate the number of steps to move forward to find the new tail, which is length - k steps from the current position (which is initially at the old tail that now points to the old head).
    • Move current forward length - k times to reach the new tail.
  5. Detach the New Head and Tail:

    • The new head is one node after the current position (current.next).
    • Set the next pointer of the current node (new tail) to null to break the circular link.
    • Return the new head as the head of the rotated list.

Algorithm Walkthrough

Let's consider the input: head = [22, 4, 10, 15, 29], k = 7

  1. Check Base Conditions: The list is not empty, has more than one element, and k is not 0. Continue with the algorithm.

  2. Calculate List Length and Form a Circular List:

    • Traverse the list [22, 4, 10, 15, 29]. The length is found to be 5.
    • Form a circular list by linking the last node (29) back to the head (22).
  3. Normalize the Rotation:

    • Normalize k by calculating k % length = 7 % 5 = 2. This means we effectively need to rotate the list by 2 positions to the right.
  4. Find the New Head and Tail:

    • Calculate the steps to the new tail: length - k = 5 - 2 = 3. Starting from the old tail (29), we move forward 3 steps and reach 10, which will be the new tail.
    • The new head is one step forward from 10, which is 15.
  5. Detach the New Head and Tail:

    • The new head is 15, and the node 10 (new tail) next pointer is set to null to break the circular link.
    • The rotated list is now [15, 29, 22, 4, 10].

By following these steps, the original list [22, 4, 10, 15, 29] when rotated by k = 7 positions to the right, results in [15, 29, 22, 4, 10].

Code

java
// public class ListNode {
//     int val;
//     ListNode next;
//     ListNode(int x) { val = x; next = null; }
// }

public class Solution {

  public ListNode rotateRight(ListNode head, int k) {
    if (head == null || head.next == null || k == 0) return head; // Base condition

    // Step 1: Calculate the length of the list
    ListNode current = head;
    int length = 1;
    while (current.next != null) {
      current = current.next;
      length++;
    }

    // Step 2: Normalize k
    k = k % length;
    if (k == 0) return head; // No rotation needed

    // Step 3: Form a circular list
    current.next = head;

    // Step 4: Traverse to the breaking point
    int stepsToNewHead = length - k;
    while (stepsToNewHead-- > 0) {
      current = current.next;
    }

    // Step 5: Detach the new head and return
    head = current.next;
    current.next = null;

    return head;
  }

  public static void main(String[] args) {
    Solution solution = new Solution();

    // Creating the linked list [22, 4, 10, 15, 29]
    ListNode head = new ListNode(22);
    head.next = new ListNode(4);
    head.next.next = new ListNode(10);
    head.next.next.next = new ListNode(15);
    head.next.next.next.next = new ListNode(29);

    // Applying the rotateRight method with k = 7
    head = solution.rotateRight(head, 7);

    // Print the rotated list
    while (head != null) {
      System.out.print(head.val + " ");
      head = head.next;
    }
  }
}

Complexity Analysis

  • Time Complexity: The time complexity of the algorithm is , where n is the number of nodes in the linked list. This is because the algorithm involves a complete traversal to calculate the length of the list, followed by a traversal to the breaking point after normalization of k.

  • Space Complexity: The space complexity of the algorithm is , indicating constant space usage. This is because the rotation is done in-place with a fixed number of variables, and no additional data structures or recursive stack space are used that would scale with the size of the input list.

🤖 Don't fully get this? Learn it with Claude

Stuck on Rotate List? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Rotate List** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Rotate List** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Rotate List**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Rotate List**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes