Skip to content

Reverse Nodes in k-Group

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

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as is.

You may not alter the values in the list’s nodes, only nodes themselves may be changed.

InputkOutputExplanation
[1, 2, 3, 4, 5]2[2, 1, 4, 3, 5]Reverse (1, 2) and (3, 4); leave 5 as is
[1, 2, 3, 4, 5]3[3, 2, 1, 4, 5]Reverse (1, 2, 3); leave (4, 5) as is
[1]1[1]Only one node, no change
[1, 2]2[2, 1]Reverse the only group of 2
  • The number of nodes in the list is n.
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000
ApproachTimeSpaceBest When
IterativeO(n)O(1)General case — no recursion overhead, more intuitive
RecursiveO(n)O(n/k)Learning recursion, practicing elegant divide-and-conquer

* Space refers to the call stack. The iterative approach uses only a few pointers.

  • Pick Iterative for the most direct and efficient solution — it clearly shows group boundaries and reversal.
  • Pick Recursive if you want to practice thinking of the problem as smaller subproblems, each handling one group independently.
Most Efficient
Iterative
O(n) time · O(1) space
Elegant
Recursive
O(n) time · O(n/k) space
★ Recommended

Process the list in groups of k nodes. For each group:

  1. Identify the boundaries of the group (k-th node and the node after it)
  2. Reverse the pointers within the group
  3. Link the reversed group back to the previous group
  4. Move forward to the next group

The key is using a dummy node as the head to simplify edge cases and tracking prevGroup to maintain links between groups.

⏱ Time O(n) One pass through list 💾 Space O(1) Only pointer variables

Input: [1, 2, 3, 4, 5], k = 2

StepActionState
Check group 1Group (1, 2) exists (2 nodes)Group boundaries identified
Reverse group 1Reverse pointers: 1 ← 2List becomes 2 → 1 → 3 → 4 → 5
Link backwardConnect dummy to reversed groupdummy → 2 → 1 → …
Check group 2Group (3, 4) exists (2 nodes)Next group boundaries identified
Reverse group 2Reverse pointers: 3 ← 4List becomes … → 4 → 3 → 5
Link backwardConnect group 1 to reversed group 2… → 1 → 4 → 3 → 5
Check group 3Only 1 node (5) left, k=2Stop (less than k nodes)
Final resultReturn dummy.next[2, 1, 4, 3, 5]

Animated walkthrough

How iterative group reversal works

Use Next or Autoplay to see how each group is identified, reversed, and reconnected.

Step 1 of 7
Waiting to begin...
Array state
Memory / lookup state

function reverseKGroupIterative(head, k):
dummy = ListNode(0)
dummy.next = head
prevGroup = dummy
while True:
kthNode = getKthNode(prevGroup, k + 1)
if not kthNode:
break
groupStart = prevGroup.next
groupEnd = kthNode
nextGroupStart = groupEnd.next
// Reverse the group from groupStart to groupEnd
prev = nextGroupStart
curr = groupStart
while curr != nextGroupStart:
nextTemp = curr.next
curr.next = prev
prev = curr
curr = nextTemp
// Link previous group to reversed current group
prevGroup.next = groupEnd
prevGroup = groupStart
return dummy.next
function getKthNode(node, k):
while node and k > 1:
node = node.next
k -= 1
return node
reverse_nodes_in_k_group_iterative.py
from typing import Optional
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_k_group_iterative(head: Optional[ListNode], k: int) -> Optional[ListNode]:
"""
Reverse nodes in k-group iteratively.
Approach: Reverse each group of k nodes in-place using iteration.
- Find the k-th node to determine the group boundary
- Reverse the group from current to k-th node
- Link the reversed group back to the previous group
- Move to the next group and repeat
Time: O(n) - visit each node once
Space: O(1) - only pointers, no extra structures
"""
# Check if there are at least k nodes to reverse
def get_kth_node(node, k):
"""Find the k-th node starting from 'node'."""
while node and k > 1:
node = node.next
k -= 1
return node
# Dummy node to simplify logic (no need to handle head specially)
dummy = ListNode(0)
dummy.next = head
prev_group = dummy # Tracks the node before the current group
while True:
# Check if there are at least k nodes remaining
kth_node = get_kth_node(prev_group, k + 1)
if not kth_node:
break
# Mark the start and end of the current group
group_start = prev_group.next
group_end = kth_node
# Save the next group's start (before we reverse the current group)
next_group_start = group_end.next
# Reverse the current group
# We reverse from group_start to group_end (inclusive)
prev = next_group_start # The node after group_end becomes the new tail
curr = group_start
while curr != next_group_start:
next_temp = curr.next
curr.next = prev
prev = curr
curr = next_temp
# Link the previous group to the reversed current group
prev_group.next = group_end
prev_group = group_start
return dummy.next
# Test cases
def create_linked_list(values):
"""Helper to create a linked list from a list of values."""
if not values:
return None
head = ListNode(values[0])
current = head
for val in values[1:]:
current.next = ListNode(val)
current = current.next
return head
def linked_list_to_list(head):
"""Helper to convert linked list to list for easy comparison."""
result = []
while head:
result.append(head.val)
head = head.next
return result
# Test
head1 = create_linked_list([1, 2, 3, 4, 5])
result1 = reverse_k_group_iterative(head1, 2)
print(linked_list_to_list(result1)) # [2, 1, 4, 3, 5]
head2 = create_linked_list([1, 2, 3, 4, 5])
result2 = reverse_k_group_iterative(head2, 3)
print(linked_list_to_list(result2)) # [3, 2, 1, 4, 5]
head3 = create_linked_list([1])
result3 = reverse_k_group_iterative(head3, 1)
print(linked_list_to_list(result3)) # [1]

Approach 2: Recursive with Self-Similar Groups

Section titled “Approach 2: Recursive with Self-Similar Groups”
elegant

Recursion allows us to think of the problem as:

  1. Reverse the first k nodes and get the new head of this group
  2. Recursively solve the rest of the list (starting from the (k+1)-th node)
  3. Connect the tail of the current group to the result of the recursive call

This approach cleanly separates each group’s processing and is conceptually elegant, though it uses O(n/k) stack space.

⏱ Time O(n) One pass, all nodes visited once 💾 Space O(n/k) Call stack depth = number of groups

Input: [1, 2, 3, 4, 5], k = 2

Recursion LevelGroupActionReturns
1(1, 2) → (3, 4, 5)Reverse (1, 2); recursively solve (3, 4, 5)head: 2, tail: 1
2(3, 4) → (5)Reverse (3, 4); recursively solve (5)head: 4, tail: 3
3(5)Only 1 node left, cannot reverseReturn 5 as is
2 returnsConnect 3 to result3 → 5 (already in place)4 → 3 → 5
1 returnsConnect 1 to result1 → 4 → 3 → 52 → 1 → 4 → 3 → 5 ✓
function reverseKGroupRecursive(head, k):
// Find the k-th node
kth = head
for i from 0 to k - 2:
if not kth:
return head
kth = kth.next
// If no k-th node, cannot reverse this group
if not kth:
return head
// Save the next group's head (after k-th)
nextGroupHead = kth.next
// Reverse from head to kth
prev = nextGroupHead
curr = head
while curr != nextGroupHead:
nextTemp = curr.next
curr.next = prev
prev = curr
curr = nextTemp
// curr is now at the old head (which is now tail)
// prev is at kth (which is now head)
// Recursively process the rest and connect
head.next = reverseKGroupRecursive(nextGroupHead, k)
return prev // Return the new head (which was kth)
reverse_nodes_in_k_group_recursive.py
from typing import Optional
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_k_group_recursive(head: Optional[ListNode], k: int) -> Optional[ListNode]:
"""
Reverse nodes in k-group recursively.
Approach: Use recursion to handle each group independently.
- Check if there are k nodes remaining
- Reverse the first k nodes
- Recursively process the rest of the list
- Connect the reversed group to the result of the recursive call
Time: O(n) - visit each node once
Space: O(n/k) - recursion depth is proportional to number of groups
"""
def reverse_helper(node, k):
"""
Reverse the first k nodes starting from 'node'.
Returns a tuple: (new_head, tail_of_reversed_group)
"""
if not node:
return node, node
# Find the k-th node
kth = node
for i in range(k - 1):
if not kth.next:
# Not enough nodes, return as is
return node, kth
kth = kth.next
# Save the next group's head
next_group_head = kth.next
# Reverse the current group (from node to kth)
prev = next_group_head
curr = node
while curr != next_group_head:
next_temp = curr.next
curr.next = prev
prev = curr
curr = next_temp
# curr is now at node (which will be the tail after reversal)
# prev is now at kth (which will be the head after reversal)
# So the head of reversed group is kth
# Recursively process the rest
node.next, _ = reverse_helper(next_group_head, k)
return kth, node
result, _ = reverse_helper(head, k)
return result
# Test cases
def create_linked_list(values):
"""Helper to create a linked list from a list of values."""
if not values:
return None
head = ListNode(values[0])
current = head
for val in values[1:]:
current.next = ListNode(val)
current = current.next
return head
def linked_list_to_list(head):
"""Helper to convert linked list to list for easy comparison."""
result = []
while head:
result.append(head.val)
head = head.next
return result
# Test
head1 = create_linked_list([1, 2, 3, 4, 5])
result1 = reverse_k_group_recursive(head1, 2)
print(linked_list_to_list(result1)) # [2, 1, 4, 3, 5]
head2 = create_linked_list([1, 2, 3, 4, 5])
result2 = reverse_k_group_recursive(head2, 3)
print(linked_list_to_list(result2)) # [3, 2, 1, 4, 5]
head3 = create_linked_list([1])
result3 = reverse_k_group_recursive(head3, 1)
print(linked_list_to_list(result3)) # [1]
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
reverse_nodes_in_k_group_space_optimized.py
"""
Solution for Reverse Nodes in k-Group
"""
def solve():
"""Implementation for approach 3 of Reverse Nodes in k-Group"""
pass
if __name__ == "__main__":
print("Solution ready")