Skip to main content

206. Reverse Linked List

easyAsked at Twilio

Reverse Linked List is Twilio's pointer-mechanics warm-up: flip a singly-linked list in place and return the new head. The grading bar is whether you write the iterative three-pointer version correctly the first try, with bonus credit for a clean recursive version.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Twilio loops.

  • Glassdoor (2026-Q1)Heavily-cited in Twilio phone-screen reports — often paired with Merge Two Sorted Lists.
  • LeetCode Discuss (2025-11)Listed across Twilio backend SWE interview reports.

Problem

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

Constraints

  • The number of nodes in the list is the range [0, 5000].
  • -5000 <= Node.val <= 5000

Examples

Example 1

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

Example 2

Input
head = [1,2]
Output
[2,1]

Example 3

Input
head = []
Output
[]

Approaches

1. Collect values to array, rebuild (rejected)

Walk the list to collect values, build a new list from the reversed array.

Time
O(n)
Space
O(n)
function reverseListBrute(head) {
  const vals = [];
  let curr = head;
  while (curr) { vals.push(curr.val); curr = curr.next; }
  vals.reverse();
  const dummy = { val: 0, next: null };
  let tail = dummy;
  for (const v of vals) { tail.next = { val: v, next: null }; tail = tail.next; }
  return dummy.next;
}

Tradeoff: O(n) extra space and allocates new nodes. Twilio rejects this immediately — the problem expects in-place pointer manipulation.

2. Iterative three-pointer (optimal)

Walk the list, flipping each node's next pointer to its predecessor.

Time
O(n)
Space
O(1)
function reverseList(head) {
  let prev = null;
  let curr = head;
  while (curr) {
    const next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return prev;
}

Tradeoff: Three pointers: prev (the new tail-of-reversed), curr (the node being flipped), next (saved before mutation). The 'save next first' ordering is the entire trick — get it wrong and you orphan the rest of the list.

3. Recursive reversal (clean variant)

Recurse to the end, then unwind by flipping each node.next.next = node.

Time
O(n)
Space
O(n) recursion stack
function reverseListRecursive(head) {
  if (head === null || head.next === null) return head;
  const newHead = reverseListRecursive(head.next);
  head.next.next = head; // flip the next node's pointer back to current
  head.next = null;       // current becomes the new tail
  return newHead;
}

Tradeoff: More elegant but O(n) stack space. For n = 5000 in JS the recursion is safe; in environments with tight stack limits, iterative wins. Bonus credit at Twilio for offering both.

Twilio-specific tips

Twilio's grading bar on Reverse Linked List is whether you write the iterative version without bugs the first try. Walk through the pointer state on a 3-node example before coding — interviewers explicitly look for that pre-coding trace. Mention the recursive version too: 'I'll write iterative for O(1) space; the recursive version is clean if you don't mind O(n) stack.' That signals you know both idioms.

Common mistakes

  • Forgetting to save `next` before reassigning `curr.next` — orphans the rest of the list and you only return the first node.
  • Returning `head` instead of `prev` — at loop exit, head still points at the original (now last) node; prev is the new head.
  • Setting head.next = null in the recursive variant in the wrong order — must happen AFTER head.next.next = head.

Follow-up questions

An interviewer at Twilio may pivot to one of these next:

  • What if you needed to reverse only nodes between positions left and right (LC 92)? (Walk to position left, then run the same flip for right - left + 1 iterations, splice back.)
  • What if you needed to reverse the list in groups of K (LC 25)? (Repeated apply of the segment-reverse with a tail pointer to splice each reversed group.)
  • How would you detect if a list is a palindrome using this technique? (Reverse the second half, walk both halves in parallel.)

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why is `prev = null` the correct initial value?

Because the original head becomes the new tail, and a tail's next pointer is null. Starting prev as null means the first iteration sets head.next = null, which is exactly what we want.

Why is the recursive version's `head.next = null` necessary?

Because without it, the original head still points forward to its old successor — creating a cycle once head.next.next = head executes. Setting it to null breaks that cycle and makes head the new tail.

Free learning resources

Curated free links for this problem.

Practice these live with InterviewChamp.AI

Drill Reverse Linked List and other Twilio interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →