Sweaty Imposter

Reverse Nodes in k-Group

HardIn-Place Reversal of LinkedListNeetCode 150SeniorOpen on LeetCodeUpdated

You're given the head of a singly linked list and a positive integer k. Starting from the head, split the list into consecutive groups of k nodes and reverse the order of the nodes within each group, then return the new head. If fewer than k nodes remain at the end, leave that last group in its original order. Change the links between nodes, not the values stored in them, and aim for O(1) extra space.

Examples

head = [1,2,3,4,5], k = 2 returns [2,1,4,3,5]

input
12345null
output
21435null
5 is a group of one, fewer than k, so it stays last.

The groups are (1,2), (3,4) and (5). Both full pairs flip to 2,1 and 4,3, while the lone 5 is fewer than k = 2 nodes, so it stays where it is.

head = [1,2,3,4,5], k = 3 returns [3,2,1,4,5]

input
12345null
output
32145null
4 and 5 are a short final group, so their order is unchanged.

The first three nodes form a full group and become 3,2,1. Only 4 and 5 remain, fewer than k = 3, so they keep their original order.

Constraints

  • 1 <= k <= n <= 5000

Hints

Hint 1

How could you reverse a fixed-length chunk in place and stitch it back into the surrounding list?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

Put a dummy node before the head and track groupPrev, the node just before the current group. Step k nodes past groupPrev to find the group's kth node; if the list ends first, stop, which leaves a short final group untouched. Otherwise reverse the group's links starting with prev = kth.next, so the group's old first node ends up pointing at the next group, then set groupPrev.next = kth and move groupPrev to that old first node. O(n) time, O(1) extra space.

Time

O(n)

Space

O(1)

Pitfall

Reversing a final group that has fewer than k nodes. Count k nodes ahead before changing any links, and save the group's first node, since after the reversal it becomes the tail that groupPrev must move to.

Solutions

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(0, head);
        ListNode groupPrev = dummy;
        while (true) {
            ListNode kth = getKth(groupPrev, k);
            if (kth == null) break;
            ListNode groupNext = kth.next;
            ListNode prev = groupNext, curr = groupPrev.next;
            while (curr != groupNext) {
                ListNode next = curr.next;
                curr.next = prev;
                prev = curr;
                curr = next;
            }
            ListNode tmp = groupPrev.next;
            groupPrev.next = kth;
            groupPrev = tmp;
        }
        return dummy.next;
    }

    private ListNode getKth(ListNode node, int k) {
        while (node != null && k > 0) {
            node = node.next;
            k--;
        }
        return node;
    }
}
Drill This