Given the head of a singly linked list, the task is to rotate the linked list clockwise by k nodes, i.e., left-shift the linked list by k nodes, where k is a given positive integer smaller than or equal to length of the linked list.
Examples:
Input: linkedlist: 2->4->7->8->9 , k = 3 Output: 8->9->2->4->7 Explanation:
Rotate 1: 4 -> 7 -> 8 -> 9 -> 2 Rotate 2: 7 -> 8 -> 9 -> 2 -> 4 Rotate 3: 8 -> 9 -> 2 -> 4 -> 7![]()
Input: linkedlist: 1->2->3->4->5->6->7->8 , k = 4 Output: 5->6->7->8->1->2->3->4![]()
Expected Time Complexity: O(n)
Expected Auxiliary Space: O(1)
Constraints:
1 <= number of nodes <= 103
1 <= node -> data <= 104
1 <= k <= number of nodes
Approach 01:
-
C++
-
Python
class Solution { public: Node* rotate(Node* head, int k) { Node* current = head; // Pointer to traverse the linked list Node* reversedPart = NULL; // Pointer to store the reversed portion of the list int remainingRotations = k; // Counter for the number of rotations Node* lastNode = head; // Traverse to the end of the list to find the last node while (lastNode->next != NULL) { lastNode = lastNode->next; } // Perform the rotation for the specified number of times while (remainingRotations != 0 && current != NULL) { Node* nextNode = current->next; // Store the next node head = nextNode; // Move the head to the next node current->next = reversedPart; // Reverse the current node's next pointer lastNode->next = current; // Attach the reversed node at the end of the list lastNode = lastNode->next; // Move to the new last node current = nextNode; // Move to the next node remainingRotations--; // Decrease the number of rotations left } return head; // Return the new head of the rotated list } };
class Solution: def rotate(self, head, k): current = head # Pointer to traverse the linked list reversedPart = None # Pointer to store the reversed portion of the list remainingRotations = k # Counter for the number of rotations # Find the last node of the list lastNode = head while lastNode.next is not None: lastNode = lastNode.next # Perform the rotation for the specified number of times while remainingRotations != 0 and current is not None: nextNode = current.next # Store the next node head = nextNode # Move the head to the next node current.next = reversedPart # Reverse the current node's next pointer lastNode.next = current # Attach the reversed node at the end of the list lastNode = lastNode.next # Move to the new last node current = nextNode # Move to the next node remainingRotations -= 1 # Decrease the number of rotations left return head # Return the new head of the rotated list
Time Complexity
- Traversing to the End:
The algorithm first traverses to the end of the linked list to find the last node. This operation takes \( O(n) \) time, where \( n \) is the number of nodes in the linked list.
- Performing Rotations:
The algorithm then performs rotations by moving nodes and updating pointers. Each rotation involves constant time operations, and the number of rotations is limited by \( k \). Therefore, in the worst case where \( k \) is equal to the number of nodes \( n \), this part also takes \( O(n) \) time.
- Overall Time Complexity:
The overall time complexity of the algorithm is \( O(n) \), considering both traversing to the end of the list and performing rotations.
Space Complexity
- Additional Space:
The algorithm uses a few extra pointers (`current`, `reversedPart`, `lastNode`, and `nextNode`). These pointers require constant space \( O(1) \), regardless of the number of nodes in the list.
- Overall Space Complexity:
The overall space complexity of the algorithm is \( O(1) \), as it uses a constant amount of extra space.