03
Groups of k (Linked List — Reversal Sub-pattern)
Repeat the sublist reversal on each full block of k nodes. A short last block is either left alone or handled as the problem says.
Signals in the problem statement
- ›
"reverse the nodes in groups of
k" - ›
"swap every two adjacent nodes" (groups of 2)
- ›
"reverse the first
k, skip the nextk, repeat"
What makes it different
Swap Nodes in Pairs is groups of 2, with the three arrows of a swap written out. Reverse Alternate K Nodes alternates a reverse turn and a skip turn. A short block on a reverse turn is still reversed in full, while a short block on a skip turn is left alone. Reverse Nodes in K Group counts k nodes before each block, so a short last block is never reversed. In all three, the connection between blocks is the step people forget.
Questions
ordered from “learn the idea” to “recognise it without help”- 1Swap Nodes in PairsWalkthroughMediumBasic Anchor·LeetCode #24
- 2Reverse Alternate K NodesWalkthroughMediumSlight Variation·GeeksforGeeks
- 3Reverse Nodes in k-GroupWalkthroughHardInterview-Level·LeetCode #25
Template
kgroup-template.cpp
// Groups of k: reverse each full block of k nodes; a short last block stays as it is.
// Count k nodes ahead first. If the block is full, reverse it, then join it to the
// previous block's tail (the old first node of this block is now its last).
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode dummy(0, head);
ListNode* groupPrev = &dummy; // the node just before the current block
while (true) {
// 1. Is there a full block of k nodes starting after groupPrev?
ListNode* kth = groupPrev;
for (int i = 0; i < k && kth != nullptr; i++) kth = kth->next;
if (kth == nullptr) break; // fewer than k left: leave the rest alone
ListNode* groupNext = kth->next; // the node after this block (saved before relinking)
ListNode* first = groupPrev->next; // the old first node; it becomes the block's last
// 2. Reverse the block with head insertion (same as the sublist template).
ListNode* prev = groupNext; // the reversed block must end at groupNext
ListNode* cur = first;
while (cur != groupNext) {
ListNode* nxt = cur->next;
cur->next = prev;
prev = cur;
cur = nxt;
}
// 3. Join: the previous block now ends at the new first node (kth).
groupPrev->next = kth;
groupPrev = first; // the old first is this block's tail for the next round
}
return dummy.next;
}Remember this · Linked List — Reversal
Trigger
Reverse whole / part / every k nodes, reorder, palindrome check, numbers stored as lists.
Think
Which piece do I reverse, and which nodes must I remember to reconnect afterwards?
Key question
Before reversing, who is the node just before the piece and who is just after?