Skip to content
dsa450for five year olds

Linked List · 2 of 36

Reverse a Linked List in group of Given Size

Cut a chain of boxes into groups of k, turn each full group around, and hook the groups back together in the same order.

HardPointer flippingMust do
Simple way
time O(n)
room O(n/k)
Clever way
time O(n)
room O(1)

The problem, simply

You get a linked list and a number k. Walk the chain in groups of k boxes. Turn each group around, but keep the groups themselves in their old order.

If the last group has fewer than k boxes, leave it as it is. Give back the new first box.

There is a second version of this problem (the GeeksforGeeks one) where the short last group is turned around too. The code changes in one line, shown in "Watch out for".

A story to remember it

Picture it

linked list
null1234567head

Seven boxes and k = 3. Groups: 1 2 3, then 4 5 6, then 7 alone. Only full groups get turned around.

  • checking
  • path
  • ignored

Examples

A normal case

In
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7, k = 3
Out
3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 7

Two full groups are turned around. Box 7 is a short group, so it stays.

Pairs

In
1 -> 2 -> 3 -> 4 -> 5, k = 2
Out
2 -> 1 -> 4 -> 3 -> 5

This is the "swap nodes in pairs" problem in disguise.

k equals the length

In
1 -> 2 -> 3, k = 3
Out
3 -> 2 -> 1

One group, the whole chain. Same as a plain reversal.

k is 1

In
1 -> 2 -> 3, k = 1
Out
1 -> 2 -> 3

A group of one box turned around is the same box.

The other version

In
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8, k = 3
Out
3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 8 -> 7

In the version where the short last group is also turned around, 7 and 8 become 8 and 7. With the main rule they would stay 7, 8.

Way 1: the simple way

Let a helper handle the rest of the chain. This is recursion.

  1. Check that there are at least k boxes from head. If not, return head unchanged.
  2. Turn the first k boxes around with the three fingers prev, curr, next.
  3. The old first box is now the end of this group. Hook it to whatever the helper returns for the rest of the chain.
  4. Return the new first box of this group.
linked listthis group, turned
null321
linked listhanded to the helper
null4567
stack
group(1)group(4)group(7)top

The first group is turned around. Box 1, its new end, waits for the helper to sort out 4 5 6 7.

  • looking now
  • done
  • ignored
java
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode probe = head;
        for (int i = 0; i < k; i++) {          // are there k boxes?
            if (probe == null) return head;    // short group: leave it
            probe = probe.next;
        }
        ListNode prev = null, curr = head;
        for (int i = 0; i < k; i++) {          // turn this group around
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        head.next = reverseKGroup(curr, k);    // old first box hooks to the rest
        return prev;                           // new first box of this group
    }
}

How long it takes: every box is counted once and flipped once, O(n). Extra room: one waiting helper per group on the call stack, O(n/k). For a long chain and a small k, that stack can get deep.

Way 2: the clever way

Do the same with a loop and a fake box in front, the dummy. The finger groupPrev always sits on the box just before the group we are about to flip.

  1. Put a dummy box D before the head. groupPrev = D.
  2. Walk k steps from groupPrev to find kth, the last box of the group. If you fall off the chain, stop.
  3. Remember groupNext = kth.next, the first box after the group.
  4. Flip the group with prev starting at groupNext, so the old first box ends up pointing to groupNext.
  5. Hook groupPrev.next = kth (the new first box), and move groupPrev to the old first box (the new last box).
  6. Repeat. The answer is D.next.

Flip groups of 3, one group at a time

01 / 09

linked list
nullD1234567groupPrev

Put a dummy box D before the head. groupPrev sits on D.

k
3
  • checking
  • done
  • answer
  • path
  • just added
  • ignored
java
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;  // find the group's last box
            if (kth == null) break;                                    // short group: done

            ListNode groupNext = kth.next;
            ListNode prev = groupNext, curr = groupPrev.next;          // flip inside the group
            while (curr != groupNext) {
                ListNode next = curr.next;
                curr.next = prev;
                prev = curr;
                curr = next;
            }
            ListNode oldFirst = groupPrev.next;
            groupPrev.next = kth;          // hook the new first box
            groupPrev = oldFirst;          // the old first box is now the group's end
        }
        return dummy.next;
    }
}

How long it takes: each box is stepped over once when counting and once when flipping, O(n). Extra room: a handful of fingers and one dummy box, O(1).

Watch out for

  • Starting prev at null inside a group cuts the chain. Start it at groupNext so the flipped group stays hooked to the rest.
  • Moving groupPrev to kth. After the flip, kth is the front of the group. groupPrev must go to the old first box, the new back.
  • The other version (turn the short last group around too): in Way 1, drop the "are there k boxes" check and flip while curr != null for at most k steps. In Way 2, when kth is null, flip the leftover boxes once and stop.
  • k of 1 or an empty chain: both ways return the chain unchanged.

What interviewers ask next

  • Swap nodes in pairs (LeetCode 24). It is this problem with k = 2.
  • Reverse only between positions m and n (LeetCode 92). Walk to box m - 1, then flip one group of size n - m + 1 the same way.
  • Reverse alternate groups: flip a group of k, then skip the next k boxes, and repeat. Add a skip loop after each hook.
  • Why is the iterative way better in production? No deep call stack, so a chain of a million boxes with k = 2 does not overflow.
  • What about a doubly linked list? Same groups, but inside a group you swap prev and next, and you also fix the prev of the box after each group.

Remember this

Grown-up words: the wagons are nodes, flipping is reversing the next pointers, the fake front wagon is a dummy node, and the helpers waiting on each other are the recursion call stack.