Skip to content

Commit 92bc6c1

Browse files
committed
[en] Add Reverse Linked List
1 parent 3439f5d commit 92bc6c1

File tree

4 files changed

+269
-1
lines changed

4 files changed

+269
-1
lines changed

en/SUMMARY.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,3 @@
259259
* [System Architecture](appendix_ii_system_design/system_architecture.md)
260260
* [Scalability](appendix_ii_system_design/scalability.md)
261261
* [Tags](tags.md)
262-

en/linked_list/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Linked List
2+
3+
This section includes common operations on linked list, such as deletion, insertion, and combination.
4+
5+
Frequently made mistakes:
6+
7+
- Not updating runner-node when traversing linked list
8+
- Not recording head node before traversing
9+
- returning incorrect pointer to node
10+
11+
The image below serves as a summarization.
12+
13+
![Linked List](../../shared-files/images/linked_list_summary_en.png)

en/linked_list/reverse_linked_list.md

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
# Reverse Linked List
2+
3+
## Question
4+
5+
- leetcode: [Reverse Linked List | LeetCode OJ](https://leetcode.com/problems/reverse-linked-list/)
6+
- lintcode: [(35) Reverse Linked List](http://www.lintcode.com/en/problem/reverse-linked-list/)
7+
8+
```
9+
Reverse a linked list.
10+
11+
Example
12+
For linked list 1->2->3, the reversed linked list is 3->2->1
13+
14+
Challenge
15+
Reverse it in-place and in one-pass
16+
```
17+
18+
## Solution1 - Non-recursively
19+
20+
It would be much easier to reverse an array than a linked list, since array supports random access with index, while singly linked list can ONLY be operated through its head node. So an approach without index is required.
21+
22+
Think about how can '1->2->3' become '3->2->1'. Starting from '1', we should turn '1->2' into '2->1', then '2->3' into '3->2', and so on. The key is how to swap two adjacent nodes.
23+
24+
```
25+
temp = head -> next;
26+
head->next = prev;
27+
prev = head;
28+
head = temp;
29+
```
30+
31+
The above code maintains two pointer, `prev` and `head`, and keeps record of next node before swapping. More detailed analysis:
32+
33+
![Reverse Linked List](../../shared-files/images/reverse_linked_list_i.jpg)
34+
35+
1. Keep record of next node
36+
2. change `head->next` to `prev`
37+
3. update `prev` with `head`, to keep moving forward
38+
4. update `head` with the record in step 1, for the sake of next loop
39+
40+
### Python
41+
42+
```python
43+
# Definition for singly-linked list.
44+
# class ListNode:
45+
# def __init__(self, x):
46+
# self.val = x
47+
# self.next = None
48+
49+
class Solution:
50+
# @param {ListNode} head
51+
# @return {ListNode}
52+
def reverseList(self, head):
53+
prev = None
54+
curr = head
55+
while curr is not None:
56+
temp = curr.next
57+
curr.next = prev
58+
prev = curr
59+
curr = temp
60+
# fix head
61+
head = prev
62+
63+
return head
64+
```
65+
66+
### C++
67+
68+
```c++
69+
/**
70+
* Definition for singly-linked list.
71+
* struct ListNode {
72+
* int val;
73+
* ListNode *next;
74+
* ListNode(int x) : val(x), next(NULL) {}
75+
* };
76+
*/
77+
class Solution {
78+
public:
79+
ListNode* reverse(ListNode* head) {
80+
ListNode *prev = NULL;
81+
ListNode *curr = head;
82+
while (curr != NULL) {
83+
ListNode *temp = curr->next;
84+
curr->next = prev;
85+
prev = curr;
86+
curr = temp;
87+
}
88+
// fix head
89+
head = prev;
90+
91+
return head;
92+
}
93+
};
94+
```
95+
96+
### Java
97+
98+
```java
99+
/**
100+
* Definition for singly-linked list.
101+
* public class ListNode {
102+
* int val;
103+
* ListNode next;
104+
* ListNode(int x) { val = x; }
105+
* }
106+
*/
107+
public class Solution {
108+
public ListNode reverseList(ListNode head) {
109+
ListNode prev = null;
110+
ListNode curr = head;
111+
while (curr != null) {
112+
ListNode temp = curr.next;
113+
curr.next = prev;
114+
prev = curr;
115+
curr = temp;
116+
}
117+
// fix head
118+
head = prev;
119+
120+
return head;
121+
}
122+
}
123+
```
124+
125+
### Source Code Analysis
126+
127+
Already covered in the solution part. One more word, the assignment of `prev` is neat and skilled.
128+
129+
### Complexity
130+
131+
Traversing the linked list, so the time complexity is $$O(n)$$. $$O(1)$$ auxiliary space complexity.
132+
133+
## Solution2 - Recursively
134+
135+
Three cases when the recursion ceases:
136+
137+
1. If given linked list is null, just return.
138+
2. If given linked list has only one node, return that node.
139+
3. If given linked list has at least two nodes, pick out the head node and regard the following nodes as a whole entity, swap them, then recurse that entity.
140+
141+
Be careful when swapping the head node (refer as `Node0`) and head of the following nodes entity (refer as 'Node1' ): First, swap `Node0` and `Node1`; Second, assign `null` to `Node0`'s next (or it would fall into infinite loop, and tail of result list won't point to `null`).
142+
143+
### Python
144+
145+
```python
146+
"""
147+
Definition of ListNode
148+
149+
class ListNode(object):
150+
151+
def __init__(self, val, next=None):
152+
self.val = val
153+
self.next = next
154+
"""
155+
class Solution:
156+
"""
157+
@param head: The first node of the linked list.
158+
@return: You should return the head of the reversed linked list.
159+
Reverse it in-place.
160+
"""
161+
def reverse(self, head):
162+
# case1: empty list
163+
if head is None:
164+
return head
165+
# case2: only one element list
166+
if head.next is None:
167+
return head
168+
# case3: reverse from the rest after head
169+
newHead = self.reverse(head.next)
170+
# reverse between head and head->next
171+
head.next.next = head
172+
# unlink list from the rest
173+
head.next = None
174+
175+
return newHead
176+
```
177+
178+
### C++
179+
180+
```c++
181+
/**
182+
* Definition of ListNode
183+
*
184+
* class ListNode {
185+
* public:
186+
* int val;
187+
* ListNode *next;
188+
*
189+
* ListNode(int val) {
190+
* this->val = val;
191+
* this->next = NULL;
192+
* }
193+
* }
194+
*/
195+
class Solution {
196+
public:
197+
/**
198+
* @param head: The first node of linked list.
199+
* @return: The new head of reversed linked list.
200+
*/
201+
ListNode *reverse(ListNode *head) {
202+
// case1: empty list
203+
if (head == NULL) return head;
204+
// case2: only one element list
205+
if (head->next == NULL) return head;
206+
// case3: reverse from the rest after head
207+
ListNode *newHead = reverse(head->next);
208+
// reverse between head and head->next
209+
head->next->next = head;
210+
// unlink list from the rest
211+
head->next = NULL;
212+
213+
return newHead;
214+
}
215+
};
216+
```
217+
218+
### Java
219+
220+
```java
221+
/**
222+
* Definition for singly-linked list.
223+
* public class ListNode {
224+
* int val;
225+
* ListNode next;
226+
* ListNode(int x) { val = x; }
227+
* }
228+
*/
229+
public class Solution {
230+
public ListNode reverse(ListNode head) {
231+
// case1: empty list
232+
if (head == null) return head;
233+
// case2: only one element list
234+
if (head.next == null) return head;
235+
// case3: reverse from the rest after head
236+
ListNode newHead = reverse(head.next);
237+
// reverse between head and head->next
238+
head.next.next = head;
239+
// unlink list from the rest
240+
head.next = null;
241+
242+
return newHead;
243+
}
244+
}
245+
```
246+
247+
### Source Code Analysis
248+
249+
case1 and case2 can be combined.What case3 returns is head of reversed list, which means it is exact the same Node (tail of origin linked list) through the recursion.
250+
251+
### Complexity
252+
253+
- [全面分析再动手的习惯:链表的反转问题(递归和非递归方式) - 木棉和木槿 - 博客园](http://www.cnblogs.com/kubixuesheng/p/4394509.html)
254+
- [data structures - Reversing a linked list in Java, recursively - Stack Overflow](http://stackoverflow.com/questions/354875/reversing-a-linked-list-in-java-recursively)
255+
- [反转单向链表的四种实现(递归与非递归,C++) | 宁心勉学,慎思笃行](http://ceeji.net/blog/reserve-linked-list-cpp/)
256+
- [iteratively and recursively Java Solution - Leetcode Discuss](https://leetcode.com/discuss/37804/iteratively-and-recursively-java-solution)
244 KB
Loading

0 commit comments

Comments
 (0)