
Problem Statement
The challenge involves a singly linked list and two integers, left and right, where left <= right. The task is to reverse the nodes of the list specifically between positions left and right, and then return the transformed list. This operation must maintain the integrity of nodes outside of the specified range—they should remain in their original order.
Examples
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
- The number of nodes in the list is
n. 1 <= n <= 500-500 <= Node.val <= 5001 <= left <= right <= n
Approach and Intuition
To tackle this problem, let’s break down our approach clearly:
- Confirm if the reversal is necessary (i.e., if
leftequalsright, no reversal occurs and the list remains unchanged). - Identify the start and end nodes of the section to be reversed—
node_at_leftandnode_at_right. - Traverse the list to locate the
left-1position as it helps to reconnect the reversed portion back with the original list. - Reverse the nodes between these markers by adjusting their
nextpointers. You will also need a mechanism to connect the portion of the list beforeleftand afterrightto this newly reversed segment. - Consider edge cases:
- Reversal at the very beginning or the very end of the list.
- Reversal of the entire list.
Now considering the constraints and examples:
- The maximum size for the list is
n = 500which suggests that a simple linear traversal is feasible within time complexity bounds. - All node values lie within a practical range, so no additional complexity for storage or calculations.
- The various edge cases presented through examples ensure that your approach needs to robustly handle lists of differing sizes and reverse operations of varying scales.
This approach ensures an efficient manipulation of pointers to achieve the desired outcome without creating a new list, thus utilizing minimal additional space.
Solutions
- C++
- Java
- C
- JavaScript
- Python
class Solution {
public:
ListNode* reverseSection(ListNode* start, int left, int right) {
if (!start) {
return nullptr;
}
ListNode *current = start, *previous = nullptr;
while (left > 1) {
previous = current;
current = current->next;
left--;
right--;
}
ListNode *connection = previous, *tail = current;
ListNode* temp = nullptr;
while (right > 0) {
temp = current->next;
current->next = previous;
previous = current;
current = temp;
right--;
}
if (connection != nullptr) {
connection->next = previous;
} else {
start = previous;
}
tail->next = current;
return start;
}
};
This article presents a solution to reverse a subsection of a singly linked list using C++.
- The solution employs a single pass approach to the linked list, achieving an efficient manner to reverse nodes between specified positions
leftandright. - The function
reverseSectionis initiated with a pointer to the starting node of the linked list and two integers,leftandright, defining the bounds within which the list should be reversed.
Furthermore, the function reverseSection performs the steps below:
- Initialize a pointer
currentto travel from the start of the list to the positionleft. - Use a
previouspointer to assist in reversing the links between the nodes from positionlefttoright. currentadvances through the linked list whilepreviousassists in reversing the connections until the sub-list is fully traversed.- Maintain pointers
connectionandtailto handle the un-reversed parts of the linked list's start and end respectively. - After the sub-list is reversed,
connectionandtailare connected to the now reversed sub-list appropriately, ensuring a smooth transition and rearrangement within the linked list. - Finally, check and handle edge cases such as when the reverse happens at the beginning of the list.
In essence, this solution efficiently performs the reversal of the linked list section in place, facilitating a straightforward approach in solving node re-arrangement tasks in linked data structures. This method maintains the integrity of the entire list while effectively modifying only the targeted section.
class Solution {
public ListNode reverseSublist(ListNode startNode, int left, int right) {
if (startNode == null) return null;
ListNode current = startNode, previous = null;
while (left > 1) {
previous = current;
current = current.next;
left--;
right--;
}
ListNode connection = previous, sublist_tail = current;
ListNode tmp = null;
while (right > 0) {
tmp = current.next;
current.next = previous;
previous = current;
current = tmp;
right--;
}
if (connection != null) {
connection.next = previous;
} else {
startNode = previous;
}
sublist_tail.next = current;
return startNode;
}
}
The provided Java solution involves a method to reverse a specific part of a singly linked list between two given positions. The method reverseSublist accepts a ListNode representing the start of the list and two integers left and right indicating the positions of the segment to reverse. The reversal only affects the nodes between these positions inclusively.
Key steps in the implementation:
- Initialize pointers
currentto the start of the list andprevioustonull. - Traverse the list until the
currentpointer reaches theleftposition, updatingcurrentandpreviousaccordingly. - Mark the node before the
leftposition asconnectionand the first node of the sub-list that needs to be reversed assublist_tail. - Continue traversing and reversing the links between
currentandpreviousuntil reaching the end of the sub-list defined byright. - Adjust the next pointers:
- Link the
connectionnode to theprevious, effectively pointing it to the last node of the reversed sub-list. - Connect the tail of the reversed sub-list (
sublist_tail) to thecurrent, which marks the node following the reversed portion.
- Link the
- If the reversed sub-list includes the first node (i.e.,
leftis 1), update the head of the list. - Return the modified list.
Considerations:
- The function handles edge cases like
nullinput by returningnull. - Properly updates connections for segments starting from the head and ensures the remaining list portions are correctly connected post reversal.
struct ListNode *reverseSublist(struct ListNode *head, int start, int end) {
if (!head) {
return NULL;
}
struct ListNode *current = head, *previous = NULL;
while (start > 1) {
previous = current;
current = current->next;
start--;
end--;
}
struct ListNode *connection = previous, *sublist_tail = current;
struct ListNode *next_node = NULL;
while (end > 0) {
next_node = current->next;
current->next = previous;
previous = current;
current = next_node;
end--;
}
if (connection)
connection->next = previous;
else
head = previous;
sublist_tail->next = current;
return head;
}
In the C programming code provided, the function reverseSublist effectively reverses a section of a singly linked list defined between two given positions, start and end. This function handles edge cases, like an empty list input, and operates directly on the list nodes to adjust pointers and reverse the sublist without creating a new list. Here's a walkthrough of how the function operates:
- Start by checking if the
headpointer is NULL. If it is, return NULL, as there's no list to process. - Establish a
currentpointer to traverse the linked list and apreviouspointer set to NULL to help in the reversal. - Navigate to the start of the sublist using a loop, updating the
currentandpreviouspointers, decrementing bothstartandendto keep track of the positions. - Keep a pointer
connectionpointing to just before the start of the sublist part andsublist_tailpointing at the start of this sublist before the reversal. - Continue the traversal. For each node in the sublist, make its
nextpointer point to thepreviousnode effectively reversing the connections between the nodes. - Once the sublist is reversed, adjust the
nextpointers ofconnectionandsublist_tailto connect the reversed sublist with the non-reversed parts of the original linked list. - If the reversed part extends to the head of the list, update the head otherwise reconnect the reversed part to the main list using the
connectionpointer.
Finally, the function correctly reconnects the last node of the reversed sublist (sublist_tail) to the current node, addressing potential disconnections in the linked list chain. The result is the original list with the specified section reversed, and the function returns the possibly new head of the list if the reversal included the first node.
var reverseSublist = function (listHead, start, end) {
if (listHead === null) {
return null;
}
let current = listHead,
previous = null;
while (start > 1) {
previous = current;
current = current.next;
start--;
end--;
}
let connection = previous,
sublistTail = current;
let temp = null;
while (end > 0) {
temp = current.next;
current.next = previous;
previous = current;
current = temp;
end--;
}
if (connection !== null) {
connection.next = previous;
} else {
listHead = previous;
}
sublistTail.next = current;
return listHead;
};
The provided JavaScript solution implements a function to reverse a specified portion of a linked list. Here's a breakdown of how the algorithm works:
Initialize pointers: The function starts by checking if the provided linked list head (
listHead) is null. If it is, return null as the list cannot be reversed.Find the sublist: Set
currentto point to the head of the list and move it along with apreviouspointer until reaching the position where reversal should start.Reverse sublist: Utilize a while loop to reverse the nodes between the specified
startandendpositions. This involves adjusting node pointers within the sublist.Reconnect sublist: After reversing the sublist, reconnect the reversed sublist with the rest of the linked list. If the sublist starts at the head, update
listHead. Otherwise, link the previous part of the list to the new start of the sublist.Handle the tail of the sublist: Link the tail of the reversed sublist (
sublistTail) to the nodecurrentwhich is where the reversing ended.
Finally, the function returns the modified list head with the specified sublist reversed. This approach leverages pointer manipulation to perform the reversal in-place, ensuring an efficient solution with constant space complexity. Be sure to update the pointers correctly to avoid common errors such as losing links or creating cycles in the linked list.
class Solution:
def reverseSublist(
self, start: Optional[ListNode], left: int, right: int
) -> Optional[ListNode]:
if not start:
return None
current, previous = start, None
while left > 1:
previous = current
current = current.next
left, right = left - 1, right - 1
sublist_tail, sublist_conn = current, previous
while right:
next_node = current.next
current.next = previous
previous = current
current = next_node
right -= 1
if sublist_conn:
sublist_conn.next = previous
else:
start = previous
sublist_tail.next = current
return start
This solution implements a function to reverse a sublist within a singly linked list in Python. To reverse a segment of the list designated by left and right indices, follow this approach:
- Initialize pointers
currentto the starting node andprevioustoNone. - Traverse the list until
currentpoints to theleft-th node, adjustingpreviousaccordingly. This sets up the start of the sublist to reverse. - Use two more pointers
sublist_tailandsublist_connto help reconnect the reversed sublist.sublist_tailinitially points to the node at positionleftandsublist_connto the node just beforeleft. - Commence the sublist reversal by iterating until
rightbecomes zero. In each iteration, adjust thenextpointers to reverse the links. - Connect the reversed sublist back to the main list:
- If there was a node before the sublist (
sublist_connis notNone), link it topreviouswhich now points to the first node of the reversed sublist. - If
sublist_connisNone, it indicates the sublist includes the first node of the list, so update the start of the list toprevious. - Connect the original
sublist_tailto the nodecurrentnow points to, which is the node right after the last reversed node.
- If there was a node before the sublist (
- Return
startas the new head of potentially modified list.
This solution ensures that only the specified segment of the list is reversed and properly connected back, maintaining the integrity of the list structure while performing the modifications in-place.