Given the head
of a singly linked list and two integers left
and right
where left <= right
, reverse the nodes of the list from position left
to position right
, and return the reversed list.
Example 1:
Input: head = [1,2,3,4,5], left = 2, right = 4 Output: [1,4,3,2,5]
Example 2:
Input: head = [5], left = 1, right = 1 Output: [5]
Constraints:
n
.1 <= n <= 500
-500 <= Node.val <= 500
1 <= left <= right <= n
Follow up: Could you do it in one pass?
This problem requires reversing a portion of a singly linked list between indices left
and right
(inclusive). The solution uses a simulation approach with a dummy head node for efficient manipulation.
Algorithm:
Dummy Node: A dummy node is created and prepended to the original linked list. This simplifies handling the edge case where the reversal starts at the head of the list.
Find the Start: The code iterates to find the node at position left - 1
(the node before the reversal starts). This node is stored in pre
.
Reverse Sublist: The code then reverses the sublist from left
to right
using iterative reversal. It keeps track of three pointers:
pre
: Points to the node before the sublist to be reversed.cur
: The current node being processed in the sublist.t
: Temporarily stores the next
node to avoid losing it during the reversal.Reconnect: After reversing the sublist, the code reconnects the reversed sublist to the rest of the list. It updates the next
pointers of the nodes at positions left -1
and right + 1
.
Return: The function returns the next
node of the dummy node (which is the head of the modified linked list).
Time and Space Complexity:
Time Complexity: O(n) - The code iterates through the linked list at most twice: once to find the starting point and once to reverse the sublist. n
represents the length of the linked list.
Space Complexity: O(1) - The solution uses a constant amount of extra space regardless of the input list size.
Code Explanation (Python3 as example, but principles apply across all languages):
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
# Handle empty or single-node list, or when left and right are the same.
if not head or not head.next or left == right:
return head
dummy = ListNode(0, head) # Dummy node for easier handling
pre = dummy
for _ in range(left - 1): # Find the node before the sublist
pre = pre.next
# Reverse the sublist
p, q = pre, pre.next #p is the node before the reversed part, q is the first node to be reversed
cur = q
for _ in range(right - left + 1):
t = cur.next #Store next node to avoid losing it
cur.next = pre # Reverse the link
pre, cur = cur, t # Move pointers
# Reconnect the reversed sublist
p.next = pre #Connect the sublist from behind
q.next = cur # Connect the sublist from the front
return dummy.next # Return the head of the modified list
The other language implementations follow the same logic with syntactic variations for each language. The key aspects – dummy node, iterative reversal, and reconnection – remain consistent.