@@ -50,7 +50,11 @@ L<sub>0</sub> → L<sub>n</sub> → L<sub>1</sub> → L<sub>n - 1</sub> → L<su
50
50
51
51
<!-- 这里可写通用的实现逻辑 -->
52
52
53
- 先通过快慢指针找到链表中点,将链表划分为左右两部分。之后反转右半部分的链表,然后将左右两个链接依次连接即可。
53
+ ** 方法一:快慢指针 + 反转链表 + 合并链表**
54
+
55
+ 我们先用快慢指针找到链表的中点,然后将链表的后半部分反转,最后将左右两个链表合并。
56
+
57
+ 时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。
54
58
55
59
<!-- tabs:start -->
56
60
@@ -65,17 +69,12 @@ L<sub>0</sub> → L<sub>n</sub> → L<sub>1</sub> → L<sub>n - 1</sub> → L<su
65
69
# self.val = val
66
70
# self.next = next
67
71
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 :
75
73
# 快慢指针找到链表中点
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
79
78
80
79
# cur 指向右半部分链表
81
80
cur = slow.next
@@ -88,8 +87,9 @@ class Solution:
88
87
cur.next = pre
89
88
pre, cur = cur, t
90
89
cur = head
91
- # 此时 cur, pre 分别指向链表左右两半的第一个节点
92
90
91
+ # 此时 cur, pre 分别指向链表左右两半的第一个节点
92
+ # 合并
93
93
while pre:
94
94
t = pre.next
95
95
pre.next = cur.next
@@ -114,19 +114,18 @@ class Solution:
114
114
*/
115
115
class Solution {
116
116
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 ) {
123
120
slow = slow. next;
124
121
fast = fast. next. next;
125
122
}
126
123
124
+ // cur 指向右半部分链表
127
125
ListNode cur = slow. next;
128
126
slow. next = null ;
129
127
128
+ // 反转右半部分链表
130
129
ListNode pre = null ;
131
130
while (cur != null ) {
132
131
ListNode t = cur. next;
@@ -136,6 +135,8 @@ class Solution {
136
135
}
137
136
cur = head;
138
137
138
+ // 此时 cur, pre 分别指向链表左右两半的第一个节点
139
+ // 合并
139
140
while (pre != null ) {
140
141
ListNode t = pre. next;
141
142
pre. next = cur. next;
@@ -147,57 +148,55 @@ class Solution {
147
148
}
148
149
```
149
150
150
- ### ** C# **
151
+ ### ** C++ **
151
152
152
- ``` cs
153
+ ``` cpp
153
154
/* *
154
155
* 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
+ * };
163
163
*/
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;
176
173
}
177
174
178
- ListNode cur = slow .next ;
179
- slow .next = null ;
175
+ // cur 指向右半部分链表
176
+ ListNode* cur = slow->next;
177
+ slow->next = nullptr;
180
178
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;
186
184
pre = cur;
187
185
cur = t;
188
186
}
189
187
cur = head;
190
188
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;
197
196
pre = t;
198
197
}
199
198
}
200
- }
199
+ };
201
200
```
202
201
203
202
### ** Go**
@@ -211,17 +210,17 @@ public class Solution {
211
210
* }
212
211
*/
213
212
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 {
219
216
slow, fast = slow.Next , fast.Next .Next
220
217
}
221
218
219
+ // cur 指向右半部分链表
222
220
cur := slow.Next
223
221
slow.Next = nil
224
222
223
+ // 反转右半部分链表
225
224
var pre *ListNode
226
225
for cur != nil {
227
226
t := cur.Next
@@ -230,6 +229,8 @@ func reorderList(head *ListNode) {
230
229
}
231
230
cur = head
232
231
232
+ // 此时 cur, pre 分别指向链表左右两半的第一个节点
233
+ // 合并
233
234
for pre != nil {
234
235
t := pre.Next
235
236
pre.Next = cur.Next
@@ -254,19 +255,19 @@ func reorderList(head *ListNode) {
254
255
* @return {void} Do not return anything, modify head in-place instead.
255
256
*/
256
257
var reorderList = function (head ) {
257
- if (! head || ! head .next ) {
258
- return ;
259
- }
258
+ // 快慢指针找到链表中点
260
259
let slow = head;
261
- let fast = head . next ;
262
- while (fast && fast .next ) {
260
+ let fast = head;
261
+ while (fast . next && fast . next .next ) {
263
262
slow = slow .next ;
264
263
fast = fast .next .next ;
265
264
}
266
265
266
+ // cur 指向右半部分链表
267
267
let cur = slow .next ;
268
268
slow .next = null ;
269
269
270
+ // 反转右半部分链表
270
271
let pre = null ;
271
272
while (cur) {
272
273
const t = cur .next ;
@@ -276,6 +277,8 @@ var reorderList = function (head) {
276
277
}
277
278
cur = head;
278
279
280
+ // 此时 cur, pre 分别指向链表左右两半的第一个节点
281
+ // 合并
279
282
while (pre) {
280
283
const t = pre .next ;
281
284
pre .next = cur .next ;
@@ -286,6 +289,57 @@ var reorderList = function (head) {
286
289
};
287
290
```
288
291
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
+
289
343
### ** TypeScript**
290
344
291
345
``` ts
0 commit comments