You are 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,6], k = 3
Output: [4,5,6,1,2,3]Explanation:
Rotate 1: [6,1,2,3,4,5]
Rotate 2: [5,6,1,2,3,4]
Rotate 3: [4,5,6,1,2,3]
Example 2:
Input: head = [0,1,2], k = 4
Output: [2,0,1]Explanation:
Rotate 1: [2,0,1]
Rotate 2: [1,2,0]
Rotate 3: [0,1,2]
Rotate 4: [2,0,1]
Constraints:
0 <= Length of the list <= 500.-100 <= Node.val <= 1000 <= k <= 2,000,000,000Before attempting this problem, you should be comfortable with:
The challenge with linked lists is that we cannot directly access elements by index. One straightforward approach is to convert the list to an array, perform the rotation using array indexing, and then write the values back to the list nodes. This trades memory for simplicity, allowing us to use familiar array rotation logic.
null.k = k % n to handle rotations larger than the list length.k values from the array.head of the modified list.# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if not head:
return None
arr, cur = [], head
while cur:
arr.append(cur.val)
cur = cur.next
n = len(arr)
k %= n
cur = head
for i in range(n - k, n):
cur.val = arr[i]
cur = cur.next
for i in range(n - k):
cur.val = arr[i]
cur = cur.next
return headRotating a linked list by k means moving the last k nodes to the front. We can do this by finding the new tail (the node at position n - k - 1), breaking the list there, and reconnecting the old tail to the old head. The key insight is that we only need to find two positions: where to break the list and where to reconnect.
null.length and the tail node.k = k % length. If k == 0, no rotation is needed.length - k - 1 (this will be the new tail).head to be the next node after the new tail.tail's next to null.tail to the old head.head.# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: ListNode, k: int) -> ListNode:
if not head:
return head
length, tail = 1, head
while tail.next:
tail = tail.next
length += 1
k = k % length
if k == 0:
return head
cur = head
for i in range(length - k - 1):
cur = cur.next
newHead = cur.next
cur.next = None
tail.next = head
return newHeadWe can simplify the two-pointer approach by first creating a circular list. Connect the tail to the head, then traverse n - k steps from the tail to find the new tail. Break the circle at that point. This approach uses a single pointer and avoids the need to track both the tail and find the break point separately.
null.tail and count the length n.tail to the head, forming a circular list.k = k % n to handle large values of k.n - k steps from the current position (the tail) to reach the new tail.head is the node after the new tail.tail's next to null.head.# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: ListNode, k: int) -> ListNode:
if not head:
return head
cur, n = head, 1
while cur.next:
n += 1
cur = cur.next
cur.next = head
k %= n
for i in range(n - k):
cur = cur.next
head = cur.next
cur.next = None
return headForgetting to check if the list is empty (head == null) or has only one node causes null pointer exceptions. A single-node list rotated by any amount remains unchanged, but the code must handle this edge case explicitly.
When k is larger than the list length or equals it, the rotation results in the same list. Failing to compute k = k % length before rotation leads to unnecessary traversals or incorrect results. Additionally, when k % length == 0, no rotation is needed and the original head should be returned.
When creating the new list structure, forgetting to set the new tail's next to null creates a cycle in the linked list. Similarly, forgetting to connect the old tail to the old head leaves the list disconnected. Both pointer updates are essential for correct rotation.