Grokking LinkedIn Coding Interview
Ask Author
Back to course home

0% completed

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

Python3
Python3

. . . .

Complexity Analysis

  • Time Complexity: The time complexity of the algorithm is O(n), 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 O(1), 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.

Mark as Completed