Bird
Raised Fist0
DSA Goprogramming

Reverse a Singly Linked List Recursive in DSA Go

Choose your learning style10 modes available
Mental Model
We flip the direction of each link by going to the end first, then reversing links on the way back.
Analogy: Imagine unstacking a pile of plates one by one to the bottom, then stacking them back in reverse order.
head -> 1 -> 2 -> 3 -> null
Dry Run Walkthrough
Input: list: 1 -> 2 -> 3 -> null
Goal: Reverse the list so it becomes 3 -> 2 -> 1 -> null using recursion
Step 1: call reverse on node 1, which calls reverse on node 2
head -> 1 -> [call on 2] -> 3 -> null
Why: We need to reach the last node before reversing links
Step 2: call reverse on node 2, which calls reverse on node 3
head -> 1 -> 2 -> [call on 3] -> null
Why: Keep going deeper until last node to start reversal
Step 3: call reverse on node 3, base case reached, return node 3
head -> 1 -> 2 -> 3 -> null
Why: Last node becomes new head of reversed list
Step 4: reverse link: node 3 points back to node 2, node 2 next set to nil
head -> 1 -> 2 ← 3 null
Why: Flip the link between 2 and 3 to reverse direction
Step 5: reverse link: node 2 points back to node 1, node 1 next set to nil
head -> 1 null ← 2 ← 3
Why: Flip the link between 1 and 2 to continue reversal
Step 6: return new head node 3 as reversed list head
3 -> 2 -> 1 -> null
Why: Final reversed list head is returned
Result:
3 -> 2 -> 1 -> null
Annotated Code
DSA Go
package main

import "fmt"

type Node struct {
	val  int
	next *Node
}

func reverseRecursive(head *Node) *Node {
	if head == nil || head.next == nil {
		return head // base case: empty or single node
	}

	newHead := reverseRecursive(head.next) // reverse rest of list

	head.next.next = head // flip link: next node points back to current
	head.next = nil      // current node becomes tail

	return newHead // return new head of reversed list
}

func printList(head *Node) {
	for head != nil {
		fmt.Printf("%d", head.val)
		if head.next != nil {
			fmt.Print(" -> ")
		}
		head = head.next
	}
	fmt.Println(" -> null")
}

func main() {
	head := &Node{val: 1}
	head.next = &Node{val: 2}
	head.next.next = &Node{val: 3}

	fmt.Print("Original list: ")
	printList(head)

	head = reverseRecursive(head)

	fmt.Print("Reversed list: ")
	printList(head)
}
if head == nil || head.next == nil {
base case: stop recursion at empty or last node
newHead := reverseRecursive(head.next)
recursive call to reverse the rest of the list
head.next.next = head
flip the next node's pointer back to current node
head.next = nil
set current node's next to nil to avoid cycle
return newHead
return new head of reversed list up the call stack
OutputSuccess
Original list: 1 -> 2 -> 3 -> null Reversed list: 3 -> 2 -> 1 -> null
Complexity Analysis
Time: O(n) because we visit each node once during recursion
Space: O(n) due to recursion call stack for n nodes
vs Alternative: Iterative reversal uses O(1) space but recursion is simpler to write and understand
Edge Cases
empty list (head is nil)
function returns nil immediately without error
DSA Go
if head == nil || head.next == nil {
single node list
function returns the single node as reversed list
DSA Go
if head == nil || head.next == nil {
When to Use This Pattern
When you see a problem asking to reverse a linked list and recursion is allowed, use recursive reversal to simplify pointer management by reversing from the end backwards.
Common Mistakes
Mistake: Not setting head.next to nil after flipping the link, causing cycles
Fix: Always set head.next = nil after reversing the pointer to avoid loops
Mistake: Returning head instead of newHead, losing the reversed list head
Fix: Return the newHead from the recursive call, which is the reversed list head
Summary
Reverses a singly linked list by recursively flipping pointers from the end to the start.
Use when you want a clean, elegant reversal using recursion instead of iteration.
The key is to reverse the rest first, then flip the current node's pointer back.

Practice

(1/5)
1. What does the recursive function to reverse a singly linked list do at each step?
easy
A. It reverses the rest of the list and then attaches the current node at the end.
B. It swaps the first two nodes and stops.
C. It deletes the current node and moves to the next.
D. It creates a new list and copies nodes in reverse order.

Solution

  1. Step 1: Understand recursion on linked list

    The function calls itself on the next node until it reaches the last node.
  2. Step 2: Attach current node after reversing rest

    After recursion returns, it sets the next node's next pointer to current node, reversing the link.
  3. Final Answer:

    It reverses the rest of the list and then attaches the current node at the end. -> Option A
  4. Quick Check:

    Recursive reversal = attach current after reversed rest [OK]
Hint: Think: reverse rest first, then fix current link [OK]
Common Mistakes:
  • Stopping recursion too early
  • Not changing next pointers correctly
  • Trying to reverse by swapping values
2. Which of the following is the correct base case for a recursive function reversing a singly linked list in Go?
easy
A. if head == nil { return nil }
B. if head == nil || head.Next == nil { return head }
C. if head.Next == nil { return nil }
D. if head == nil && head.Next == nil { return nil }

Solution

  1. Step 1: Identify base case for recursion

    The recursion stops when the list is empty or has one node, so head is nil or head.Next is nil.
  2. Step 2: Return head in base case

    Return the head node itself because a single node or empty list is already reversed.
  3. Final Answer:

    if head == nil || head.Next == nil { return head } -> Option B
  4. Quick Check:

    Base case = empty or single node returns head [OK]
Hint: Base case: empty or single node returns itself [OK]
Common Mistakes:
  • Returning nil for single node
  • Using && instead of || in condition
  • Missing base case causing infinite recursion
3. What is the output linked list after running this recursive reverse function on the list 1 -> 2 -> 3 -> nil?
func reverse(head *Node) *Node {
    if head == nil || head.Next == nil {
        return head
    }
    newHead := reverse(head.Next)
    head.Next.Next = head
    head.Next = nil
    return newHead
}
medium
A. nil
B. 1 -> 2 -> 3 -> nil
C. 2 -> 3 -> 1 -> nil
D. 3 -> 2 -> 1 -> nil

Solution

  1. Step 1: Trace recursion calls

    Calls reverse on 2 -> 3 -> nil, then on 3 -> nil (base case returns 3).
  2. Step 2: Reverse links on return

    Sets 3.Next to 2, 2.Next to 1, and 1.Next to nil, reversing the list.
  3. Final Answer:

    3 -> 2 -> 1 -> nil -> Option D
  4. Quick Check:

    Reversed list = 3->2->1 [OK]
Hint: Follow recursion bottom-up to see reversed links [OK]
Common Mistakes:
  • Not setting head.Next to nil causing cycle
  • Returning wrong node as new head
  • Confusing order of pointer assignments
4. Identify the bug in this recursive reverse function for a singly linked list:
func reverse(head *Node) *Node {
    if head == nil {
        return nil
    }
    newHead := reverse(head.Next)
    head.Next.Next = head
    return newHead
}
medium
A. head.Next.Next should be head.Next
B. Incorrect return type
C. Missing base case for single node causing nil pointer dereference
D. No bug, code is correct

Solution

  1. Step 1: Check base case correctness

    Base case only checks if head is nil, but not if head.Next is nil, causing head.Next.Next to panic if head.Next is nil.
  2. Step 2: Identify nil pointer dereference

    When head.Next is nil, head.Next.Next causes runtime error because head.Next is nil.
  3. Final Answer:

    Missing base case for single node causing nil pointer dereference -> Option C
  4. Quick Check:

    Base case must handle single node to avoid nil panic [OK]
Hint: Always check base case for nil and single node [OK]
Common Mistakes:
  • Ignoring single node base case
  • Assuming head.Next is never nil
  • Not setting head.Next to nil after reversal
5. Given a singly linked list with nodes containing values 10 -> 20 -> 30 -> 40 -> nil, what will be the list after applying this recursive reverse function?
func reverse(head *Node) *Node {
    if head == nil || head.Next == nil {
        return head
    }
    newHead := reverse(head.Next)
    head.Next.Next = head
    head.Next = nil
    return newHead
}
Choose the correct final linked list.
hard
A. 40 -> 30 -> 20 -> 10 -> nil
B. 10 -> 20 -> 30 -> 40 -> nil
C. 40 -> 10 -> 20 -> 30 -> nil
D. 30 -> 20 -> 10 -> 40 -> nil

Solution

  1. Step 1: Recursively reverse from tail

    Recursion reaches node with value 40 (base case), then reverses links back up.
  2. Step 2: Re-link nodes in reverse order

    Each node's next node points back to itself, and original head's next is set to nil.
  3. Final Answer:

    40 -> 30 -> 20 -> 10 -> nil -> Option A
  4. Quick Check:

    Reversed list = 40->30->20->10 [OK]
Hint: Reverse order means last node becomes new head [OK]
Common Mistakes:
  • Forgetting to set head.Next to nil
  • Returning old head instead of new head
  • Misordering nodes after reversal
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard