2022-06-15 22:12:54 +08:00
# Leetcode Reverse-Linked-List
#### 2022-06-15 22:07
---
2022-09-03 15:41:36 +08:00
2022-06-15 22:12:54 +08:00
##### Algorithms:
2022-09-03 15:41:36 +08:00
#algorithm #recursion #iteration
2022-06-15 22:12:54 +08:00
##### Data structures:
2022-09-03 15:41:36 +08:00
#DS #linked_list
2022-06-15 22:12:54 +08:00
##### Difficulty:
2022-09-03 15:41:36 +08:00
2022-09-06 20:22:48 +08:00
#leetcode #coding_problem #difficulty_medium
2022-09-03 15:41:36 +08:00
2022-06-15 22:53:24 +08:00
##### Lists:
2022-09-03 15:41:36 +08:00
#CS_list_need_understanding #CS_list_need_practicing
2022-07-02 08:46:55 +08:00
##### Revisions:
2022-09-03 15:41:36 +08:00
2022-07-02 08:46:55 +08:00
2022-07-02
2022-09-20 13:19:16 +08:00
2022-09-20
2022-09-03 15:41:36 +08:00
2022-06-15 22:12:54 +08:00
##### Related topics:
2022-09-03 15:41:36 +08:00
2022-06-15 22:12:54 +08:00
##### Links:
2022-09-03 15:41:36 +08:00
2022-06-15 22:32:23 +08:00
- [Link to problem ](https://leetcode.com/problems/reverse-linked-list/ )
2022-09-03 15:41:36 +08:00
---
2022-06-15 22:12:54 +08:00
### Problem
2022-09-03 15:41:36 +08:00
2022-06-15 22:32:23 +08:00
Given the `head` of a singly linked list, reverse the list, and return _the reversed list_ .
2022-09-03 15:41:36 +08:00
2022-06-15 22:12:54 +08:00
#### Examples
2022-09-03 15:41:36 +08:00
2022-06-15 22:32:23 +08:00
**Example 1:**
![](https://assets.leetcode.com/uploads/2021/02/19/rev1ex1.jpg)
```markdown
**Input:** head = [1,2,3,4,5]
**Output:** [5,4,3,2,1]
```
**Example 2:**
![](https://assets.leetcode.com/uploads/2021/02/19/rev1ex2.jpg)
```markdown
**Input:** head = [1,2]
**Output:** [2,1]
```
**Example 3:**
2022-06-15 22:12:54 +08:00
```markdown
2022-06-15 22:32:23 +08:00
**Input:** head = []
**Output:** []
2022-06-15 22:12:54 +08:00
```
#### Constraints
2022-09-03 15:41:36 +08:00
- The number of nodes in the list is the range `[0, 5000]` .
- `-5000 <= Node.val <= 5000`
2022-06-15 22:12:54 +08:00
### Thoughts
2022-09-20 13:19:16 +08:00
Many ways to implement this. from slow but easy ones, to
fast but hard ones:
#### Easy way:
2022-06-15 22:53:24 +08:00
I thought a slow O(n ^ 2) hybrid solution, while there are better algorithms, using in-place insert, or recursion.
2022-09-20 13:19:16 +08:00
#### Fast way:
2022-09-20 13:48:08 +08:00
#### Recursion
2022-06-15 22:53:24 +08:00
The in place insert is easier to understand, and simple to implement, using a very clever trick.
2022-06-15 22:12:54 +08:00
2022-06-16 13:54:44 +08:00
> [!summary] My thoughts on the recursion algorithm
2022-09-03 15:41:36 +08:00
>
2022-06-16 13:54:44 +08:00
> #### How was that implemented?
2022-09-03 15:41:36 +08:00
>
2022-06-16 13:54:44 +08:00
> The recursion algorithm takes the advantage of the fact that when you change the node's next properties or nodes after that, the node before still points to the same node, so when every node after **tmp** is reversed, simply move **tmp** after **tmp->next**, which now points to the tail of reversed list
2022-09-03 15:41:36 +08:00
>
2022-06-16 13:54:44 +08:00
> #### Why return the last element of the original list?
2022-09-03 15:41:36 +08:00
>
2022-06-16 13:54:44 +08:00
> It returns the last element in the original list to make sure you are always returning the head of the reversed array, since for any reversed list, the last one comes first.
2022-07-18 15:39:57 +08:00
> **The only recursive part is returning the _tail node_.**
2022-06-16 13:54:44 +08:00
2022-09-20 13:48:08 +08:00
##### Iteration
The iteration method use two pointers:
- one that points to the new head, as an anchor
- The other one points to nodes we need to iterate over:
2022-06-15 22:12:54 +08:00
### Solution
2022-09-03 15:41:36 +08:00
2022-06-15 22:53:24 +08:00
I've referred to this guy: https://leetcode.com/problems/reverse-linked-list/discuss/58130/C%2B%2B-Iterative-and-Recursive
2022-07-02 08:27:19 +08:00
Insertion, iteration
2022-09-03 15:41:36 +08:00
2022-06-15 22:53:24 +08:00
```cpp
class Solution {
public:
ListNode *reverseList(ListNode *head) {
ListNode *pre = new ListNode(0), *cur = head;
// pre is before head, and insert any element after pre.
pre->next = head;
while (cur & & cur->next) {
2022-06-15 23:14:20 +08:00
// temp points to head
2022-06-15 22:53:24 +08:00
ListNode *temp = pre->next;
2022-06-15 23:14:20 +08:00
// Move cur->next after pre.
2022-06-15 22:53:24 +08:00
pre->next = cur->next;
2022-06-15 23:14:20 +08:00
// Fix pointers, because cur->next is unchanged when changing position.
2022-06-15 22:53:24 +08:00
cur->next = cur->next->next;
pre->next->next = temp;
}
return pre->next;
}
};
2022-06-15 23:14:20 +08:00
```
Recursion:
2022-09-03 15:41:36 +08:00
2022-09-20 13:28:10 +08:00
2022-09-20 version
```cpp
class Solution {
public:
ListNode *reverseList(ListNode *head) {
// Recursion
// Base case: no need to reverse:
if (head == nullptr || head->next == nullptr) {
return head;
}
// assuming we have the head of reversed sub-list
// head->next still points to next one in the unchanged order,
// or the tail of the reversed list
auto newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
};
```
2022-06-15 23:14:20 +08:00
```cpp
class Solution {
public:
ListNode *reverseList(ListNode *head) {
2022-07-02 08:27:19 +08:00
// Recursion
if (head == nullptr || head->next == nullptr) {
// base case: return the tail
2022-06-15 23:14:20 +08:00
return head;
}
2022-07-02 08:27:19 +08:00
// have to call itself before modifying, since head->next will point to
// nullptr
ListNode *newHead = reverseList(head->next);
2022-06-16 13:54:44 +08:00
2022-06-15 23:14:20 +08:00
head->next->next = head;
2022-07-02 08:27:19 +08:00
head->next = nullptr;
2022-06-16 13:54:44 +08:00
2022-07-02 08:27:19 +08:00
return newHead;
2022-06-15 23:14:20 +08:00
}
};
2022-09-03 15:41:36 +08:00
```