Reverse Nodes in K-Group
Overview
Reverse nodes in k-group means reversing the list in chunks of k nodes: reverse the first k nodes, then the next k, and so on. If the remaining nodes are fewer than k, leave them unchanged. Use a Dummy Head and repeat: (1) check that there are at least k nodes left from the current tail, (2) reverse that segment with the usual Reverse In-Place loop, (3) reconnect the segment to the previous part and to the rest, (4) move the tail pointer past the reversed segment. All in O(n) time and O(1) space.
Key idea: Each group of k nodes is reversed the same way as a full list: prev, curr, next; run k iterations. The only extra work is finding the group boundaries and wiring the group's new head and tail into the list.
When to Use
- Reverse nodes in k-group β Exact problem.
- Swap pairs β Special case k = 2; same pattern.
How It Works
- Dummy: dummy.next = head; tail = dummy (tail = last node before the next group).
- Loop: While there are at least k nodes after tail:
- Count k nodes from tail.next (or traverse to the k-th node) to get the group head and the node after the group.
- Reverse the k nodes (standard in-place reverse: start with prev = tail, curr = tail.next; run k steps).
- After reverse, the "new head" of the group is the last node of the original segment; the "new tail" is the original group head. Set tail.next = new head (the reversed group head), and new tail.next = the node after the group.
- Set tail = the new tail (old group head) for the next iteration.
- Return dummy.next.
Example 1: Reverse Nodes in K-Group
Problem: Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list. If the number of nodes is not a multiple of k, leave the remainder as is.
function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
const dummy = new ListNode(-1);
dummy.next = head;
let tail: ListNode = dummy;
while (true) {
let count = 0;
let curr: ListNode | null = tail.next;
while (curr !== null && count < k) {
curr = curr.next;
count++;
}
if (count !== k) break;
const groupHead = tail.next!;
let prev: ListNode | null = tail;
curr = tail.next;
for (let i = 0; i < k; i++) {
const next = curr!.next;
curr!.next = prev;
prev = curr;
curr = next;
}
tail.next = prev;
groupHead.next = curr;
tail = groupHead;
}
return dummy.next;
}- Time: O(n), Space: O(1).
Edge Cases
- k = 1 β No reversal; return head.
- List shorter than k β Count < k; break and return head.
- Length = k β One full reverse; tail becomes the old head, which correctly points to null.
- Length = 2k β Two groups; after first group, tail is at old head; second group reverses and tail.next points to null.
Common Mistakes
- Reconnecting the segment β After reversing, the group's new head is in
prevand the new tail isgroupHead; set tail.next = prev and groupHead.next = curr (the rest of the list). - Reversal range β Reverse exactly k nodes; start with prev = tail (so the first node's next becomes tail), and run the loop k times.
- Advancing tail β tail must move to the node that will be the "previous" of the next group, i.e. the old head of the group just reversed (groupHead).
Time and Space Complexity
- Time: O(n) β each node is touched a constant number of times.
- Space: O(1).
Summary
- Reverse in k-group: Dummy + tail; while k nodes remain, reverse them in-place, wire tail.next and groupTail.next, set tail = groupTail; return dummy.next.
- Builds on Dummy Head and Reverse In-Place. For k=2 see Swap Nodes in Pairs.