Given the head of a singly linked list, reverse the list and return the reversed list's head.

Input: head = [1, 2, 3, 4, 5]
Output: [5, 4, 3, 2, 1]
Input: head = [1, 2]
Output: [2, 1]
Input: head = []
Output: []

Contents

The key idea is to traverse the list and reverse the next pointer of each node to point to its previous node. We maintain three pointers: prev, curr, and next.

class ListNode { int val; ListNode next; ListNode(int val) { this.val = val; } } public class ReverseLinkedList { public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode next = curr.next; // save next curr.next = prev; // reverse pointer prev = curr; // move prev forward curr = next; // move curr forward } return prev; // prev is now the new head } }
Complexity Analysis:

Time complexity: O(n) where n is the number of nodes in the linked list, since we visit each node once.
Space complexity: O(1) as we only use a constant number of pointers.

In the recursive approach, we recurse to the end of the list and then fix the pointers on the way back.

public class ReverseLinkedList { public ListNode reverseListRecursive(ListNode head) { // Base case: empty list or single node if (head == null || head.next == null) { return head; } // Reverse the rest of the list ListNode newHead = reverseListRecursive(head.next); // Make head.next point back to head head.next.next = head; head.next = null; return newHead; } }
Complexity Analysis:

Time complexity: O(n) since every node is visited exactly once through the recursion.
Space complexity: O(n) due to the recursion call stack, which can go n levels deep.