Reverse Nodes in k-Group
Reverse every consecutive group of k nodes in place; leave the trailing remainder untouched.
4 min read
linked-list
Problem#
Reverse every k-sized consecutive group of nodes. If the final group has fewer than k nodes, leave it as is.
Examples#
[1,2,3,4,5], k = 2→[2,1,4,3,5][1,2,3,4,5], k = 3→[3,2,1,4,5]
Constraints#
1 <= k <= n <= 5000.
Hints#
Hint 1
Use a dummy head. For each group, first probe
k ahead to confirm the group exists; then reverse it in place; then splice. Approach#
Dummy node + group pointer. Per group: walk k steps ahead to confirm completeness, reverse those k nodes, splice tail (now-reversed group’s old head) back to the rest.
Solution#
class Solution {public: ListNode* reverseKGroup(ListNode* head, int k) { ListNode dummy(0, head); ListNode* groupPrev = &dummy; while (true) { ListNode* kth = groupPrev; for (int i = 0; i < k && kth; ++i) kth = kth->next; if (!kth) break; ListNode* groupNext = kth->next; // Reverse [groupPrev->next .. kth]. ListNode *prev = groupNext, *curr = groupPrev->next; while (curr != groupNext) { ListNode* nxt = curr->next; curr->next = prev; prev = curr; curr = nxt; } ListNode* oldHead = groupPrev->next; groupPrev->next = kth; groupPrev = oldHead; } return dummy.next; }};func reverseKGroup(head *ListNode, k int) *ListNode { dummy := &ListNode{Next: head} groupPrev := dummy for { kth := groupPrev for i := 0; i < k && kth != nil; i++ { kth = kth.Next } if kth == nil { break } groupNext := kth.Next prev, curr := groupNext, groupPrev.Next for curr != groupNext { nxt := curr.Next curr.Next = prev prev = curr curr = nxt } oldHead := groupPrev.Next groupPrev.Next = kth groupPrev = oldHead } return dummy.Next}from typing import Optional
class Solution: def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]: dummy = ListNode(0, head) group_prev = dummy while True: kth: Optional[ListNode] = group_prev for _ in range(k): if kth is None: break kth = kth.next if kth is None: break group_next = kth.next prev, curr = group_next, group_prev.next while curr is not group_next: nxt = curr.next curr.next = prev prev = curr curr = nxt old_head = group_prev.next group_prev.next = kth group_prev = old_head return dummy.nextfunction reverseKGroup(head, k) { const dummy = new ListNode(0, head); let groupPrev = dummy; while (true) { let kth = groupPrev; for (let i = 0; i < k && kth; i++) kth = kth.next; if (!kth) break; const groupNext = kth.next; let prev = groupNext, curr = groupPrev.next; while (curr !== groupNext) { const nxt = curr.next; curr.next = prev; prev = curr; curr = nxt; } const oldHead = groupPrev.next; groupPrev.next = kth; groupPrev = oldHead; } return dummy.next;}class Solution { public ListNode reverseKGroup(ListNode head, int k) { ListNode dummy = new ListNode(0, head); ListNode groupPrev = dummy; while (true) { ListNode kth = groupPrev; for (int i = 0; i < k && kth != null; i++) kth = kth.next; if (kth == null) break; ListNode groupNext = kth.next; ListNode prev = groupNext, curr = groupPrev.next; while (curr != groupNext) { ListNode nxt = curr.next; curr.next = prev; prev = curr; curr = nxt; } ListNode oldHead = groupPrev.next; groupPrev.next = kth; groupPrev = oldHead; } return dummy.next; }}function reverseKGroup(head: ListNode | null, k: number): ListNode | null { const dummy = new ListNode(0, head); let groupPrev: ListNode = dummy; while (true) { let kth: ListNode | null = groupPrev; for (let i = 0; i < k && kth !== null; i++) kth = kth.next; if (kth === null) break; const groupNext: ListNode | null = kth.next; let prev: ListNode | null = groupNext; let curr: ListNode | null = groupPrev.next; while (curr !== groupNext) { const nxt: ListNode | null = curr!.next; curr!.next = prev; prev = curr; curr = nxt; } const oldHead: ListNode = groupPrev.next!; groupPrev.next = kth; groupPrev = oldHead; } return dummy.next;}Editorial#
The dummy node makes splicing the first group uniform. The probe-then-reverse pattern guarantees we only reverse groups of exactly k. The reversal uses groupNext as the stop sentinel (instead of null) so the tail of the reversed group correctly links to the rest of the list.
Complexity#
- Time: O(n).
- Space: O(1).
Concept revision#
Related#