Skip to content

Commit 2069181

Browse files
authoredJul 31, 2023
feat: add solutions to lc problem: No.143 (doocs#1350)
No.0143.Reorder List
1 parent a61f1d5 commit 2069181

File tree

8 files changed

+354
-261
lines changed

8 files changed

+354
-261
lines changed
 

‎solution/0100-0199/0143.Reorder List/README.md

+118-64
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ L<sub>0</sub> → L<sub>n</sub> → L<sub>1</sub> → L<sub>n - 1</sub> → L<su
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53-
先通过快慢指针找到链表中点,将链表划分为左右两部分。之后反转右半部分的链表,然后将左右两个链接依次连接即可。
53+
**方法一:快慢指针 + 反转链表 + 合并链表**
54+
55+
我们先用快慢指针找到链表的中点,然后将链表的后半部分反转,最后将左右两个链表合并。
56+
57+
时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。
5458

5559
<!-- tabs:start -->
5660

@@ -65,17 +69,12 @@ L<sub>0</sub> → L<sub>n</sub> → L<sub>1</sub> → L<sub>n - 1</sub> → L<su
6569
# self.val = val
6670
# self.next = next
6771
class Solution:
68-
def reorderList(self, head: ListNode) -> None:
69-
"""
70-
Do not return anything, modify head in-place instead.
71-
"""
72-
if head is None or head.next is None:
73-
return
74-
72+
def reorderList(self, head: Optional[ListNode]) -> None:
7573
# 快慢指针找到链表中点
76-
slow, fast = head, head.next
77-
while fast and fast.next:
78-
slow, fast = slow.next, fast.next.next
74+
fast = slow = head
75+
while fast.next and fast.next.next:
76+
slow = slow.next
77+
fast = fast.next.next
7978

8079
# cur 指向右半部分链表
8180
cur = slow.next
@@ -88,8 +87,9 @@ class Solution:
8887
cur.next = pre
8988
pre, cur = cur, t
9089
cur = head
91-
# 此时 cur, pre 分别指向链表左右两半的第一个节点
9290

91+
# 此时 cur, pre 分别指向链表左右两半的第一个节点
92+
# 合并
9393
while pre:
9494
t = pre.next
9595
pre.next = cur.next
@@ -114,19 +114,18 @@ class Solution:
114114
*/
115115
class Solution {
116116
public void reorderList(ListNode head) {
117-
if (head == null || head.next == null) {
118-
return;
119-
}
120-
ListNode slow = head;
121-
ListNode fast = head.next;
122-
while (fast != null && fast.next != null) {
117+
// 快慢指针找到链表中点
118+
ListNode fast = head, slow = head;
119+
while (fast.next != null && fast.next.next != null) {
123120
slow = slow.next;
124121
fast = fast.next.next;
125122
}
126123

124+
// cur 指向右半部分链表
127125
ListNode cur = slow.next;
128126
slow.next = null;
129127

128+
// 反转右半部分链表
130129
ListNode pre = null;
131130
while (cur != null) {
132131
ListNode t = cur.next;
@@ -136,6 +135,8 @@ class Solution {
136135
}
137136
cur = head;
138137

138+
// 此时 cur, pre 分别指向链表左右两半的第一个节点
139+
// 合并
139140
while (pre != null) {
140141
ListNode t = pre.next;
141142
pre.next = cur.next;
@@ -147,57 +148,55 @@ class Solution {
147148
}
148149
```
149150

150-
### **C#**
151+
### **C++**
151152

152-
```cs
153+
```cpp
153154
/**
154155
* Definition for singly-linked list.
155-
* public class ListNode {
156-
* public int val;
157-
* public ListNode next;
158-
* public ListNode(int val=0, ListNode next=null) {
159-
* this.val = val;
160-
* this.next = next;
161-
* }
162-
* }
156+
* struct ListNode {
157+
* int val;
158+
* ListNode *next;
159+
* ListNode() : val(0), next(nullptr) {}
160+
* ListNode(int x) : val(x), next(nullptr) {}
161+
* ListNode(int x, ListNode *next) : val(x), next(next) {}
162+
* };
163163
*/
164-
public class Solution {
165-
public void ReorderList(ListNode head) {
166-
if (head == null || head.next == null)
167-
{
168-
return;
169-
}
170-
ListNode slow = head;
171-
ListNode fast = head.next;
172-
while (fast != null && fast.next != null)
173-
{
174-
slow = slow.next;
175-
fast = fast.next.next;
164+
class Solution {
165+
public:
166+
void reorderList(ListNode* head) {
167+
// 快慢指针找到链表中点
168+
ListNode* fast = head;
169+
ListNode* slow = head;
170+
while (fast->next && fast->next->next) {
171+
slow = slow->next;
172+
fast = fast->next->next;
176173
}
177174

178-
ListNode cur = slow.next;
179-
slow.next = null;
175+
// cur 指向右半部分链表
176+
ListNode* cur = slow->next;
177+
slow->next = nullptr;
180178

181-
ListNode pre = null;
182-
while (cur != null)
183-
{
184-
ListNode t = cur.next;
185-
cur.next = pre;
179+
// 反转右半部分链表
180+
ListNode* pre = nullptr;
181+
while (cur) {
182+
ListNode* t = cur->next;
183+
cur->next = pre;
186184
pre = cur;
187185
cur = t;
188186
}
189187
cur = head;
190188

191-
while (pre != null)
192-
{
193-
ListNode t = pre.next;
194-
pre.next = cur.next;
195-
cur.next = pre;
196-
cur = pre.next;
189+
// 此时 cur, pre 分别指向链表左右两半的第一个节点
190+
// 合并
191+
while (pre) {
192+
ListNode* t = pre->next;
193+
pre->next = cur->next;
194+
cur->next = pre;
195+
cur = pre->next;
197196
pre = t;
198197
}
199198
}
200-
}
199+
};
201200
```
202201

203202
### **Go**
@@ -211,17 +210,17 @@ public class Solution {
211210
* }
212211
*/
213212
func reorderList(head *ListNode) {
214-
if head == nil || head.Next == nil {
215-
return
216-
}
217-
slow, fast := head, head.Next
218-
for fast != nil && fast.Next != nil {
213+
// 快慢指针找到链表中点
214+
fast, slow := head, head
215+
for fast.Next != nil && fast.Next.Next != nil {
219216
slow, fast = slow.Next, fast.Next.Next
220217
}
221218

219+
// cur 指向右半部分链表
222220
cur := slow.Next
223221
slow.Next = nil
224222

223+
// 反转右半部分链表
225224
var pre *ListNode
226225
for cur != nil {
227226
t := cur.Next
@@ -230,6 +229,8 @@ func reorderList(head *ListNode) {
230229
}
231230
cur = head
232231

232+
// 此时 cur, pre 分别指向链表左右两半的第一个节点
233+
// 合并
233234
for pre != nil {
234235
t := pre.Next
235236
pre.Next = cur.Next
@@ -254,19 +255,19 @@ func reorderList(head *ListNode) {
254255
* @return {void} Do not return anything, modify head in-place instead.
255256
*/
256257
var reorderList = function (head) {
257-
if (!head || !head.next) {
258-
return;
259-
}
258+
// 快慢指针找到链表中点
260259
let slow = head;
261-
let fast = head.next;
262-
while (fast && fast.next) {
260+
let fast = head;
261+
while (fast.next && fast.next.next) {
263262
slow = slow.next;
264263
fast = fast.next.next;
265264
}
266265

266+
// cur 指向右半部分链表
267267
let cur = slow.next;
268268
slow.next = null;
269269

270+
// 反转右半部分链表
270271
let pre = null;
271272
while (cur) {
272273
const t = cur.next;
@@ -276,6 +277,8 @@ var reorderList = function (head) {
276277
}
277278
cur = head;
278279

280+
// 此时 cur, pre 分别指向链表左右两半的第一个节点
281+
// 合并
279282
while (pre) {
280283
const t = pre.next;
281284
pre.next = cur.next;
@@ -286,6 +289,57 @@ var reorderList = function (head) {
286289
};
287290
```
288291

292+
### **C#**
293+
294+
```cs
295+
/**
296+
* Definition for singly-linked list.
297+
* public class ListNode {
298+
* public int val;
299+
* public ListNode next;
300+
* public ListNode(int val=0, ListNode next=null) {
301+
* this.val = val;
302+
* this.next = next;
303+
* }
304+
* }
305+
*/
306+
public class Solution {
307+
public void ReorderList(ListNode head) {
308+
// 快慢指针找到链表中点
309+
ListNode slow = head;
310+
ListNode fast = head;
311+
while (fast.next != null && fast.next.next != null) {
312+
slow = slow.next;
313+
fast = fast.next.next;
314+
}
315+
316+
// cur 指向右半部分链表
317+
ListNode cur = slow.next;
318+
slow.next = null;
319+
320+
// 反转右半部分链表
321+
ListNode pre = null;
322+
while (cur != null) {
323+
ListNode t = cur.next;
324+
cur.next = pre;
325+
pre = cur;
326+
cur = t;
327+
}
328+
cur = head;
329+
330+
// 此时 cur, pre 分别指向链表左右两半的第一个节点
331+
// 合并
332+
while (pre != null) {
333+
ListNode t = pre.next;
334+
pre.next = cur.next;
335+
cur.next = pre;
336+
cur = pre.next;
337+
pre = t;
338+
}
339+
}
340+
}
341+
```
342+
289343
### **TypeScript**
290344

291345
```ts

0 commit comments

Comments
 (0)
Please sign in to comment.