150NeetCode 150

45.Reverse Nodes in K Group

HardLinked List ยท 11/11

Problem

Given the head of a linked list and a positive integer k, reverse the nodes of the list k at a time and return the modified list.

If the number of nodes left at the end is not a multiple of k, those final nodes stay in their original order. You may not change node values โ€” only the nodes themselves (their next pointers) may be rearranged.

Examples

Input:  head = [1, 2, 3, 4, 5], k = 2
Output: [2, 1, 4, 3, 5]
Explanation: Groups [1,2] and [3,4] are reversed; [5] is shorter than k and stays.
Input:  head = [1, 2, 3, 4, 5], k = 3
Output: [3, 2, 1, 4, 5]
Explanation: Only [1,2,3] forms a full group; [4,5] is left as is.

Constraints

  • The number of nodes in the list is n.
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000
  • Follow-up: solve it with O(1) extra memory.

๐Ÿ’ก Key Insight

Each group is just the classic "reverse a linked list" applied to k nodes, plus careful reconnection: the node before the group (groupPrev) must point to the group's new first node, and the group's new last node (its old first) must point to whatever follows the group. Before reversing, walk k steps ahead to confirm a full group exists โ€” that check is what leaves the short tail untouched. A dummy node makes the first group identical to every other.

Brute Force (Stack of Nodes)

TimeO(n)SpaceO(k)

Intuition

A stack reverses order for free. Push k nodes; if you managed to push all k, pop them and append in reversed order. If you hit the end before k, the leftover nodes are appended unchanged.

Algorithm

  1. dummy, tail = dummy, curr = head.
  2. Loop:
    • Push up to k nodes from curr onto a stack, advancing curr.
    • If the stack has fewer than k nodes, attach tail.next = groupStart (unchanged) and stop.
    • Otherwise pop each node and append it to tail.
  3. Set tail.next = curr after each full group so the list stays connected; return dummy.next.

Visualization

1 -> 2 -> 3 -> 4 -> 5, k = 2
push 1,2 -> pop 2,1   result: 2 -> 1
push 3,4 -> pop 4,3   result: 2 -> 1 -> 4 -> 3
push 5   -> only 1 < k, attach 5 as is
result: 2 -> 1 -> 4 -> 3 -> 5

Code

java
import java.util.ArrayDeque;
import java.util.Deque;

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(0);
        ListNode tail = dummy;
        ListNode curr = head;
        Deque<ListNode> stack = new ArrayDeque<>();
        while (curr != null) {
            ListNode groupStart = curr;
            while (curr != null && stack.size() < k) {
                stack.push(curr);
                curr = curr.next;
            }
            if (stack.size() < k) {
                tail.next = groupStart; // short tail: keep original order
                return dummy.next;
            }
            while (!stack.isEmpty()) {
                tail.next = stack.pop();
                tail = tail.next;
            }
            tail.next = curr; // keep the list connected to the rest
        }
        return dummy.next;
    }
}

Complexity

  • Time: O(n) โ€” every node is pushed and popped at most once.
  • Space: O(k) โ€” the stack holds one group at a time.

Complexity Comparison

Approach Time Space
Stack of Nodes O(n) O(k)
Recursion O(n) O(n/k)
Iterative In-Place Reversal O(n) O(1)

Common Pitfalls

  • Reversing the final short group โ€” always confirm k nodes exist before reversing.
  • Initialising prev = null when reversing a group; the group's old first node then points to null and the rest of the list is lost. Start with prev = groupNext.
  • Forgetting to update groupPrev to the group's old first node (now its last), not to kth.
  • Swapping node values instead of relinking nodes โ€” the problem explicitly forbids changing values.
  • In the stack version, not setting tail.next = curr after each group, which can leave a cycle back into the reversed nodes.