Given the head
of a linked list, reverse the nodes of the list k
at a time, and return the modified list.
k
is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k
then left-out nodes, in the end, should remain as it is.
You may not alter the values in the list's nodes, only nodes themselves may be changed.
Example 1:
Input: head = [1,2,3,4,5], k = 2 Output: [2,1,4,3,5]
Example 2:
Input: head = [1,2,3,4,5], k = 3 Output: [3,2,1,4,5]
Constraints:
n
.1 <= k <= n <= 5000
0 <= Node.val <= 1000
Follow-up: Can you solve the problem in O(1)
extra memory space?
Given a linked list's head and an integer k
, reverse the nodes of the list k
at a time, and return the modified list. k
is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k
, the left-out nodes at the end should remain as they are. You can only change the nodes themselves, not their values.
The most efficient approach is an iterative solution that reverses groups of k
nodes at a time. It avoids recursion's overhead.
Dummy Node: Create a dummy node to simplify handling the head of the list. This node points to the actual head.
Iteration: Iterate through the linked list using two pointers: pre
(previous group's tail) and cur
(current group's head).
Group Extraction: For each iteration, cur
moves k
nodes forward. If cur
becomes null
before reaching k
nodes, it means there are fewer than k
nodes left, and the remaining list should not be reversed.
Reversal: If k
nodes are found, reverse the sublist starting at pre.next
and ending at cur
. A separate reverse
helper function efficiently handles this.
Connection: After reversal, connect the reversed sublist back to the main list by connecting pre
to the new head of the reversed sublist and the tail of the reversed sublist to the next group's head (cur.next
).
Advance: Update pre
to point to the tail of the reversed sublist, and continue the process.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
dummy = ListNode(next=head) # Dummy node for easy head handling
pre = dummy
while True:
count = 0
cur = pre
for i in range(k):
cur = cur.next
if not cur: # Not enough nodes for a full group
return dummy.next
count +=1
#Reverse the next k nodes
next_group = cur.next #store next group
tail = pre.next
for i in range(k):
temp = tail.next
tail.next = cur.next
cur.next = tail
tail = temp
pre.next = cur
pre = tail
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0, head);
ListNode pre = dummy;
while (true) {
ListNode cur = pre;
int count = 0;
for (int i = 0; i < k; i++) {
cur = cur.next;
if (cur == null) {
return dummy.next;
}
count++;
}
ListNode nextGroup = cur.next;
ListNode tail = pre.next;
for (int i = 0; i < k; i++) {
ListNode temp = tail.next;
tail.next = cur.next;
cur.next = tail;
tail = temp;
}
pre.next = cur;
pre = tail;
}
}
}
(Similar code can be implemented in other languages like C++, JavaScript, Go, etc., following the same logic.)
This iterative approach provides a clear, concise, and efficient solution to the "Reverse Nodes in k-Group" problem. Remember to handle edge cases such as an empty list or k
being greater than the list length.