4
4
5
5
链表相关的核心点
6
6
7
- - null/nil 异常处理
8
- - dummy node 哑巴节点
9
- - 快慢指针
7
+ - null/nil 异常处理,多写点None的分支没事的;
8
+ - dummy node 哑节点:避免处理head导致的问题,反正最后返回就是返回dummy.next;
9
+ - 快慢指针,有时也会有三个指针的情况,比如反转链表。
10
10
- 插入一个节点到排序链表
11
11
- 从一个链表中移除一个节点
12
- - 翻转链表
12
+ - 翻转链表:不好搞了就创一个新的链表从头开始,只操作头节点。链表问题搞不清楚都可以这么思考;
13
13
- 合并两个链表
14
- - 找到链表的中间节点
14
+ - 找到链表的中间节点。
15
15
16
16
## 常见题型
17
17
@@ -72,16 +72,39 @@ class Solution:
72
72
return dummy.next
73
73
```
74
74
75
- 注意点
76
- • A->B->C 删除 B,A.next = C
77
- • 删除用一个 Dummy Node 节点辅助(允许头节点可变)
78
- • 访问 X.next 、X.value 一定要保证 X != nil
75
+ 注意点:
76
+
77
+ - A->B->C 删除 B,A.next = C
78
+ - 删除用一个 Dummy Node 节点辅助(允许头节点可变)
79
+ - 访问 X.next 、X.value 一定要保证 X != nil
79
80
80
81
### [ reverse-linked-list] ( https://leetcode-cn.com/problems/reverse-linked-list/ )
81
82
82
83
> 反转一个单链表。
83
84
84
- - 思路:将当前结点放置到头结点
85
+ - 思路:将当前结点放置到头结点,新创一个链表,把原来链表中的节点一个一个挪过去。
86
+ - 注意:` next_ = curr.next ` 步骤,没有这一步的话,` cur.next ` 会在` dummy_new_head.next = dummy_old_head ` 的操作中被修改掉。
87
+ - 上面的解法是下面解法的更清晰的版本。
88
+
89
+ ``` python
90
+ def reverseListI (self , head : Optional[ListNode]) -> Optional[ListNode]:
91
+
92
+ dummy = ListNode()
93
+ curr = head
94
+
95
+ while curr:
96
+
97
+ next_ = curr.next
98
+
99
+ dummy_old_head = dummy.next
100
+ dummy.next = curr
101
+ dummy_new_head = dummy.next
102
+ dummy_new_head.next = dummy_old_head
103
+
104
+ curr = next_
105
+
106
+ return dummy.next
107
+ ```
85
108
86
109
``` Python
87
110
class Solution :
@@ -100,7 +123,9 @@ class Solution:
100
123
101
124
return head
102
125
```
126
+
103
127
- Recursive method is tricky
128
+
104
129
``` Python
105
130
class Solution :
106
131
def reverseList (self , head : ListNode) -> ListNode:
@@ -147,7 +172,7 @@ class Solution:
147
172
148
173
### [ merge-two-sorted-lists] ( https://leetcode-cn.com/problems/merge-two-sorted-lists/ )
149
174
150
- > 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的 。
175
+ > 将两个升序链表合并为一个新的升序链表并返回。** 新链表 ** 是通过拼接给定的两个链表的所有节点组成的 。
151
176
152
177
- 思路:通过 dummy node 链表,连接各个元素
153
178
@@ -177,27 +202,31 @@ class Solution:
177
202
178
203
> 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 * x* 的节点都在大于或等于 * x* 的节点之前。
179
204
180
- - 思路:将大于 x 的节点,放到另外一个链表,最后连接这两个链表
205
+ - 思路:将大于 x 的节点,放到另外一个链表,最后连接这两个链表。
206
+ - 注意:依然是注意curr.next = None,切断和原来链表的链接,避免成环,导致超时和爆内存(无限循环)。
181
207
182
- ``` go
208
+ ``` python
183
209
class Solution :
184
- def partition (self, head: ListNode , x: int ) -> ListNode :
185
-
186
- p = l = ListNode ()
187
- q = s = ListNode (next=head)
188
-
189
- while q.next is not None :
190
- if q.next .val < x:
191
- q = q.next
210
+ def partition (self , head : Optional[ListNode], x : int ) -> Optional[ListNode]:
211
+
212
+ gt_dummy, lt_dummy = ListNode(), ListNode()
213
+ gt_curr, lt_curr = gt_dummy, lt_dummy
214
+
215
+ curr = head
216
+ while curr:
217
+ next_ = curr.next
218
+ curr.next = None
219
+ if curr.val < x:
220
+ lt_curr.next = curr
221
+ lt_curr = lt_curr.next
192
222
else :
193
- p.next = q.next
194
- q.next = q.next .next
195
- p = p.next
196
-
197
- p.next = None
198
- q.next = l.next
199
-
200
- return s.next
223
+ gt_curr.next = curr
224
+ gt_curr = gt_curr.next
225
+ curr = next_
226
+
227
+ lt_curr.next = gt_dummy.next
228
+
229
+ return lt_dummy.next
201
230
```
202
231
203
232
哑巴节点使用场景
0 commit comments