The Problem

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

Each node contains a value and a next pointer to the following node (or None for the last node). Reverse all the next pointers so that the last node becomes the new head and the original head points to None.

Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?

Interactive Visualization

Speed:
Linked List Visualization
Code
fun reverseList(head: ListNode?): ListNode? {    var prev: ListNode? = null    var curr = head    while (curr != null) {        val nextNode = curr.next  // save next        curr.next = prev          // reverse pointer        prev = curr               // advance prev        curr = nextNode           // advance curr    }    return prev
Status
Press Step or Play to begin.

How It Works

Key Insight

To reverse a linked list in-place, we only need to change where each node's next pointer points. Instead of pointing forward, each node should point backward to the previous node. We can do this in a single pass using three pointers: prev, curr, and next_node. The trick is saving the next reference before overwriting it, so we don't lose our place in the list.

The Algorithm

  • Initialize: prev = None, curr = head
  • Save next: store next_node = curr.next before we break the link
  • Reverse pointer: set curr.next = prev โ€” this reverses the arrow
  • Advance prev: move prev = curr โ€” prev catches up to curr
  • Advance curr: move curr = next_node โ€” curr moves to the saved next node
  • Repeat: continue until curr is None (end of list)
  • Return: prev is now the new head of the reversed list

Complexity

Time O(n)
Space O(1)

We visit each node exactly once, and we only use three pointer variables โ€” no extra data structures or recursion stack needed.