// LEETCODE #25 · HARD
Reverse Nodes in k-Group
Iterative Block Reversal with Tail Reconnection (O(n) Time O(1) Space) LeetCode 25 Difficulty: Hard Intuition The problem asks us to reverse nodes in groups of size k .
Iterative Block Reversal with Tail Reconnection (O(n) Time | O(1) Space)
LeetCode #25 | Difficulty: Hard
Intuition
The problem asks us to reverse nodes in groups of size k.
Instead of reversing the entire list at once, we can think in terms of independent blocks of size k:
- If a block has exactly
knodes → reverse it. - If fewer than
knodes remain → leave them as it is.
So the problem reduces to repeating three operations:
- Check if
knodes exist. - Reverse exactly
knodes. - Reconnect the reversed block with the previous and next parts.
The key challenge is handling pointer connections correctly between groups.
Approach
-
Maintain:
head→ start of current group.cur→ used to check if k nodes exist.newHead→ head of final modified list.kTail→ tail of previously reversed group.
-
For each group:
- Move
curforwardksteps to check ifknodes are available. - If count == k:
- Reverse the
knodes using helperreverseLL. - If this is the first reversed group, update
newHead. - Connect previous group’s tail (
kTail) to the reversed head. - Update
kTailto current group’s original head (which becomes tail after reversal). - Move
headforward to the next group start.
- Reverse the
- Move
-
If fewer than
knodes remain:- Attach remaining nodes as-is.
-
Return:
newHeadif at least one reversal happened.- Otherwise original
head.
Helper Function
reverseLL(head, k):
- Iteratively reverses exactly
knodes. - Uses standard 3-pointer technique.
- Returns new head of reversed block.
Complexity
-
Time complexity: O(n)
Each node is visited a constant number of times. Every node participates in exactly one reversal.
-
Space complexity: O(1)
Only a few pointer variables are used. No recursion or extra data structures.
Code
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseLL(ListNode* head, int k) {
ListNode* cur = head;
ListNode* pre = nullptr;
while(k>0) {
ListNode* temp = cur;
cur = cur->next;
temp->next = pre;
pre = temp;
k--;
}
return pre;
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* cur = head;
ListNode* newHead = nullptr;
ListNode* kTail = nullptr;
while(cur) {
int count = 0;
cur = head;
while(count<k && cur) {
cur = cur->next;
count++;
}
if(count==k) {
ListNode* revHead = reverseLL(head, k);
if(newHead == nullptr) newHead = revHead;
if(kTail!=nullptr) kTail->next = revHead;
kTail = head;
head = cur;
}
}
if(kTail!=nullptr) kTail->next = head;
return (newHead==nullptr) ? head : newHead;
}
};