Reverse a linked list

LeetCode problem 206. Reverse Linked List.

## Problem description

Reverse a singly linked list.

Example
* **Input:** 1 → 2 → 3 → 4 → 5 → NULL
* **Output:** 5 → 4 → 3 → 2 → 1 → NULL

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

## Iterative method

The main idea of the **iterative method** is to reverse the pointing relationship of the nodes one-by-one.

```
**Before**
       1 → 2 → 3 → 4 → 5 → NULL

**After**
NULL ← 1 ← 2 ← 3 ← 4 ← 5

```

We can use a `prev` pointer and a `curr` pointer to iterate over the elements.

The `prev` pointer is used to save the previous element of `curr` in the list, so that `curr` can be updated to point to the correct target.

Each iteration does the following:

1. Use `ListNode *next = curr->next;` to save the original next pointer of `curr`.
2. Set `curr->next = prev;`. We update the linking relationship *in-place* so that there is no copying of the nodes.
3. Move forward `prev`: `prev = curr;`.
4. Move forward `curr`: `curr = next;`.

Stop when `curr` hits the end, i.e. `curr == nullptr`.

### Complexity analysis

#### Time complexity

Since we processed each node exactly once, the time complexity is **O(n)**.

#### Space complexity

Stack
Since we only used the `prev`, `curr`, and `next` pointers, the space complexity on stack is O(1).
Heap
Since we did not allocate any new objects, the space complexity on heap is O(1).
So the total space complexity is **O(1)**.

### Solution

#### C++

```
/\*\*
 \* Definition for singly-linked list.
 \* struct ListNode {
 \* int val;
 \* ListNode \*next;
 \* ListNode() : val(0), next(nullptr) {}
 \* ListNode(int x) : val(x), next(nullptr) {}
 \* ListNode(int x, ListNode \*next) : val(x), next(next) {}
 \* };
 \*/
class Solution {
public:
 ListNode\* reverseList(ListNode\* head) {
 // iterative approach

 if ((head == nullptr) || (head->next == nullptr)) {
 return head;
 }

 ListNode \*prev = nullptr, \*curr = head;
 // go over each node, one by one
 while (curr != nullptr) {
 // save next pointer of current
 ListNode \*next = curr->next;
 // redirect
 curr->next = prev;
 // move forward
 prev = curr;
 curr = next;
 }
 // now prev reaches the original tail (becomes the new head)
 head = prev;
 return head;
 }
};

```

#### Java

```
/\*\*
 \* Definition for singly-linked list.
 \* public class ListNode {
 \* int val;
 \* ListNode next;
 \* ListNode() {}
 \* ListNode(int val) { this.val = val; }
 \* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 \* }
 \*/
class Solution {
 public ListNode reverseList(ListNode head) {
 // iterative approach

 if ((head == null) || (head.next == null)) {
 return head;
 }

 ListNode prev = null, curr = head;
 // go over each node, one by one
 while (curr != null) {
 // save next pointer of current
 ListNode next = curr.next;
 // redirect
 curr.next = prev;
 // move forward
 prev = curr;
 curr = next;
 }
 // now prev reaches the original tail (becomes the new head)
 head = prev;
 return head;
 }
}

```

## Recursive method

We can also use the recursive method.

One important property useful for recursion that after reversing a linked list, **the original head becomes the tail**, and **the original tail becomes the new head**.

Hence, for a input linked list with *n* nodes, we would be reversing the sub-lists at the end with sizes *n-1*, *n-2*, …, 2, 1. There will be *n-1* recursive calls.

In each recursion we can obtain a new head and a new tail (i.e. the original head of that sub-list). Then we can join that tail with the original head of the upper level, and the original head of the upper level becomes the new tail. Calling this procedure recursively allows us to reverse the entire linked list.

### Complexity analysis

#### Time complexity

For an input with *n* nodes there are *n-1* recursive calls. Each recursion level takes O(1) time to generate the new tail for the upper recursion level.

So the time complexity in total is **O(n)**.

#### Space complexity

Stack
For each recursion we need to temporarily the `next` pointer of the head of the sub-list. The `next` pointer is used to generate the tail after getting out from each recursion. So the space complexity on stack is O(n).
Heap
We did not allocate any new objects. So the space complexity on heap is O(1).

The total space complexity is **O(n)**.

### Solution

#### C++ solution

```
/\*\*
 \* Definition for singly-linked list.
 \* struct ListNode {
 \* int val;
 \* ListNode \*next;
 \* ListNode() : val(0), next(nullptr) {}
 \* ListNode(int x) : val(x), next(nullptr) {}
 \* ListNode(int x, ListNode \*next) : val(x), next(next) {}
 \* };
 \*/
class Solution {
public:
 ListNode\* reverseList(ListNode\* head) {
 // recursive approach
 // for each call of reverseList, return the new head
 // head becomes tail after reversing

 // base cases of recursion
 if ((head == nullptr) || (head->next == nullptr)) {
 return head;
 }

 // recursive call
 ListNode \*next = head->next;
 ListNode \*newHead = reverseList(next);
 next->next = head;
 head->next = nullptr;
 return newHead;
 }
};

```

#### Java solution

```
/\*\*
 \* Definition for singly-linked list.
 \* public class ListNode {
 \* int val;
 \* ListNode next;
 \* ListNode() {}
 \* ListNode(int val) { this.val = val; }
 \* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 \* }
 \*/
class Solution {
 public ListNode reverseList(ListNode head) {
 // recursive approach
 // for each call of reverseList, return the new head
 // head becomes tail after reversing

 // base cases of recursion
 if ((head == null) || (head.next == null)) {
 return head;
 }

 // recursive call
 ListNode next = head.next;
 ListNode newHead = reverseList(next);
 next.next = head;
 head.next = null;
 return newHead;
 }
}

```

## Notes

* In doing problems of linked lists, we should always maintain the access to head node by the caller context.
* After reversing a linked list (*in-place*), the original head becomes the tail.
* We should let the tail terminate by setting its `next` pointer to `null`. Otherwise we will end up with a cyclic linked list, which is definitely not a correct output.

## External links

* Reverse a linked list (Archive)
* Recursively Reversing a linked list (A simple implementation) (Archive)