Reverse a Linked List (Recursive)

Given Linked List
Assets/Leetcode/LinkedList/reverse_linked_list/recursive_approach/1.png
Need to reverse the given linked list which will eventually look like this.
Assets/Leetcode/LinkedList/reverse_linked_list/recursive_approach/2.png
Read the problem description for more detail.

Intuition

Before solving the problem let's think how a Linked List can be reversed. Simple by reversing the connected link, more technically by modifying the .next pointer. Instead of pointing the next node .next pointer will point to it's previous node.

Assets/Leetcode/LinkedList/reverse_linked_list/recursive_approach/3.png
The Idea is Starting from the Head, we will reach at the Last Node (you can say bottom) of the Linked List and start reversing from there. Let's take a variable called revHead which is going to be the Head of our final Reversed Linked List.

class Solution(object):
	def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
		revHead = head

What will happen when the function got executed?
So the main function has called our reverseList function and it looks like this from the view of call stack
Assets/Leetcode/LinkedList/reverse_linked_list/recursive_approach/4.png

Going into the Depth

As you can see our current Head is 1 which has a non null node next to it. So we can call reverseList with the next node of the current Head like reverseList(head.next). We can keep doing this until the Head has Non Null Next Node.

class Solution(object):
	def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
		revHead = head
		if head.next:
			revHead = self.reverseList(head.next)

Let's visualize the recursion call-stack.
Assets/Leetcode/LinkedList/reverse_linked_list/recursive_approach/5.png
Okey, We just stepped onto the Last Node of the Linked List 3. So there will be no further recursion call. Now look at the Actual Linked List once again now.
Assets/Leetcode/LinkedList/reverse_linked_list/recursive_approach/6.png

Pull up Reversed Head and Reverse Nodes Right to Left

We are at the Last Node and the Last Node has no one except NULL next to it, meaning nothing to reverse. Just connect the Head with NULL, you will see the reason shortly. Also we will return the revHead (reversed head) to it's previous call from the call-stack.

class Solution(object):
	def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
		revHead = head
		if head.next:
			revHead = self.reverseList(head.next)
			# reverseList(3) will return here with revHead=3
			# so we are at reverseList(2) where 
			# head = 2
			# head.next = 3
			# so we need to reverse the link here. 
			# we will see this process in the visual next
			rightNode = head.next
			# now rightNode is like 3 -> None
			rightNode.next = head
			# so now the 3 -> 2, 
			# though node 2 still pointing to node 3, like 3 <- 2
			# but that will be fixed in the next like
		
		# fixing the next of current head
		head.next = None
		return revHead

Let's visualize this code
Assets/Leetcode/LinkedList/reverse_linked_list/recursive_approach/7.png
Have you noticed We are updating Reverse Head from it's previous call. It's just to keep track of the Reverse Head in every state, kind off Pulling Up 💪 an Anchor ⚓️ from the deep 🌊 😎
Meanwhile We also done reversing the .next pointer between the Pairs of Node.
So we can just return the reversed head to call it done.

Complete Code Snippet

class Solution(object):
	def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
		# adding a safety check incase the given head itself is null
		if not head:
			return None
		
		# initializing the reversed head with the head .
		# it will be reinitialized by teh current head of every recursion call
		revHead = head
		
		# we will keep recursing until we step onto the last node
		if head.next:
			# recursion call with the next node
			revHead = self.reverseList(head.next)
			# connecting right node with head (left node)
			rightNode = head.next
			rightNode.next = head
		
		# connecting current head (left node) with None
		head.next = None
		return revHead

Complexity Analysis

Time Complexity is O(N) where N is the number of nodes in the Linked List.
The Space Complexity is O(N) since there is N number of calls in the call-stack. Because, the recursion maintains a Call Stack which would take additional O(N) space

So solving Reverse a Linked List in iterative approach is the Optimal Solution for this. Because, that will take only O(N) Time Complexity with no additional space complexity.


Thanks for Stopping by! Happy Leet coding.

Connect with me on

Github LinkedIn Gmail Youtube