Skip to content

Commit 859c150

Browse files
authoredFeb 3, 2024
feat: add solutions to lcci problems: No.02.03,02.04 (#2307)
* No.02.03.Delete Middle Node * No.02.04.Partition List
1 parent 08f9dc0 commit 859c150

File tree

10 files changed

+247
-174
lines changed

10 files changed

+247
-174
lines changed
 

‎lcci/02.03.Delete Middle Node/README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525

2626
## 解法
2727

28-
### 方法一
28+
### 方法一:节点赋值
29+
30+
我们可以将当前节点的值替换为下一个节点的值,然后删除下一个节点。这样就可以达到删除当前节点的目的。
31+
32+
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
2933

3034
<!-- tabs:start -->
3135

@@ -39,10 +43,6 @@
3943

4044
class Solution:
4145
def deleteNode(self, node):
42-
"""
43-
:type node: ListNode
44-
:rtype: void Do not return anything, modify node in-place instead.
45-
"""
4646
node.val = node.next.val
4747
node.next = node.next.next
4848
```

‎lcci/02.03.Delete Middle Node/README_EN.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020

2121
## Solutions
2222

23-
### Solution 1
23+
### Solution 1: Node Assignment
24+
25+
We can replace the value of the current node with the value of the next node, and then delete the next node. This way, we can achieve the purpose of deleting the current node.
26+
27+
The time complexity is $O(1)$, and the space complexity is $O(1)$.
2428

2529
<!-- tabs:start -->
2630

@@ -34,10 +38,6 @@
3438

3539
class Solution:
3640
def deleteNode(self, node):
37-
"""
38-
:type node: ListNode
39-
:rtype: void Do not return anything, modify node in-place instead.
40-
"""
4141
node.val = node.next.val
4242
node.next = node.next.next
4343
```

‎lcci/02.03.Delete Middle Node/Solution.py

-4
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,5 @@
77

88
class Solution:
99
def deleteNode(self, node):
10-
"""
11-
:type node: ListNode
12-
:rtype: void Do not return anything, modify node in-place instead.
13-
"""
1410
node.val = node.next.val
1511
node.next = node.next.next

‎lcci/02.04.Partition List/README.md

+83-59
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,17 @@
4242

4343
### 方法一:拼接链表
4444

45-
创建两个链表,一个存放小于 `x` 的节点,另一个存放大于等于 `x` 的节点,之后进行拼接即可。
45+
我们创建两个链表 $left$ 和 $right$,分别用于存储小于 $x$ 的节点和大于等于 $x$ 的节点。
46+
47+
然后我们用两个指针 $p1$ 和 $p2$ 分别指向 $left$ 和 $right$ 的最后一个节点,初始时 $p1$ 和 $p2$ 都指向一个虚拟头节点。
48+
49+
接下来我们遍历链表 $head$,如果当前节点的值小于 $x$,我们就将当前节点添加到 $left$ 链表的末尾,即 $p1.next = head$,然后令 $p1 = p1.next$;否则我们就将当前节点添加到 $right$ 链表的末尾,即 $p2.next = head$,然后令 $p2 = p2.next$。
50+
51+
遍历结束后,我们将 $left$ 链表的尾节点指向 $right$ 链表的第一个有效节点,即 $p1.next = right.next$,然后将 $right$ 链表的尾节点指向空节点,即 $p2.next = null$。
52+
53+
最后我们返回 $left$ 链表的第一个有效节点。
54+
55+
时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。
4656

4757
<!-- tabs:start -->
4858

@@ -56,19 +66,19 @@
5666

5767
class Solution:
5868
def partition(self, head: ListNode, x: int) -> ListNode:
59-
l1, l2 = ListNode(0), ListNode(0)
60-
cur1, cur2 = l1, l2
69+
left, right = ListNode(0), ListNode(0)
70+
p1, p2 = left, right
6171
while head:
6272
if head.val < x:
63-
cur1.next = head
64-
cur1 = cur1.next
73+
p1.next = head
74+
p1 = p1.next
6575
else:
66-
cur2.next = head
67-
cur2 = cur2.next
76+
p2.next = head
77+
p2 = p2.next
6878
head = head.next
69-
cur1.next = l2.next
70-
cur2.next = None
71-
return l1.next
79+
p1.next = right.next
80+
p2.next = None
81+
return left.next
7282
```
7383

7484
```java
@@ -77,29 +87,27 @@ class Solution:
7787
* public class ListNode {
7888
* int val;
7989
* ListNode next;
80-
* ListNode() {}
81-
* ListNode(int val) { this.val = val; }
82-
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
90+
* ListNode(int x) { val = x; }
8391
* }
8492
*/
8593
class Solution {
8694
public ListNode partition(ListNode head, int x) {
87-
ListNode l1 = new ListNode(0);
88-
ListNode l2 = new ListNode(0);
89-
ListNode cur1 = l1, cur2 = l2;
90-
while (head != null) {
95+
ListNode left = new ListNode(0);
96+
ListNode right = new ListNode(0);
97+
ListNode p1 = left;
98+
ListNode p2 = right;
99+
for (; head != null; head = head.next) {
91100
if (head.val < x) {
92-
cur1.next = head;
93-
cur1 = cur1.next;
101+
p1.next = head;
102+
p1 = p1.next;
94103
} else {
95-
cur2.next = head;
96-
cur2 = cur2.next;
104+
p2.next = head;
105+
p2 = p2.next;
97106
}
98-
head = head.next;
99107
}
100-
cur1.next = l2.next;
101-
cur2.next = null;
102-
return l1.next;
108+
p1.next = right.next;
109+
p2.next = null;
110+
return left.next;
103111
}
104112
}
105113
```
@@ -110,35 +118,58 @@ class Solution {
110118
* struct ListNode {
111119
* int val;
112120
* ListNode *next;
113-
* ListNode() : val(0), next(nullptr) {}
114-
* ListNode(int x) : val(x), next(nullptr) {}
115-
* ListNode(int x, ListNode *next) : val(x), next(next) {}
121+
* ListNode(int x) : val(x), next(NULL) {}
116122
* };
117123
*/
118124
class Solution {
119125
public:
120126
ListNode* partition(ListNode* head, int x) {
121-
ListNode* l1 = new ListNode();
122-
ListNode* l2 = new ListNode();
123-
ListNode* cur1 = l1;
124-
ListNode* cur2 = l2;
125-
while (head != nullptr) {
127+
ListNode* left = new ListNode(0);
128+
ListNode* right = new ListNode(0);
129+
ListNode* p1 = left;
130+
ListNode* p2 = right;
131+
for (; head; head = head->next) {
126132
if (head->val < x) {
127-
cur1->next = head;
128-
cur1 = cur1->next;
133+
p1->next = head;
134+
p1 = p1->next;
129135
} else {
130-
cur2->next = head;
131-
cur2 = cur2->next;
136+
p2->next = head;
137+
p2 = p2->next;
132138
}
133-
head = head->next;
134139
}
135-
cur1->next = l2->next;
136-
cur2->next = nullptr;
137-
return l1->next;
140+
p1->next = right->next;
141+
p2->next = nullptr;
142+
return left->next;
138143
}
139144
};
140145
```
141146
147+
```go
148+
/**
149+
* Definition for singly-linked list.
150+
* type ListNode struct {
151+
* Val int
152+
* Next *ListNode
153+
* }
154+
*/
155+
func partition(head *ListNode, x int) *ListNode {
156+
left, right := &ListNode{}, &ListNode{}
157+
p1, p2 := left, right
158+
for ; head != nil; head = head.Next {
159+
if head.Val < x {
160+
p1.Next = head
161+
p1 = p1.Next
162+
} else {
163+
p2.Next = head
164+
p2 = p2.Next
165+
}
166+
}
167+
p1.Next = right.Next
168+
p2.Next = nil
169+
return left.Next
170+
}
171+
```
172+
142173
```ts
143174
/**
144175
* Definition for singly-linked list.
@@ -153,30 +184,23 @@ public:
153184
*/
154185

155186
function partition(head: ListNode | null, x: number): ListNode | null {
156-
if (head == null) {
157-
return head;
158-
}
159-
let cur = head;
160-
while (cur.next != null) {
161-
let node = cur.next;
162-
if (node.val < x) {
163-
[head, node.next, cur.next] = [node, head, node.next];
187+
const [left, right] = [new ListNode(), new ListNode()];
188+
let [p1, p2] = [left, right];
189+
for (; head; head = head.next) {
190+
if (head.val < x) {
191+
p1.next = head;
192+
p1 = p1.next;
164193
} else {
165-
cur = cur.next;
194+
p2.next = head;
195+
p2 = p2.next;
166196
}
167197
}
168-
return head;
198+
p1.next = right.next;
199+
p2.next = null;
200+
return left.next;
169201
}
170202
```
171203

172204
<!-- tabs:end -->
173205

174-
### 方法二:头插法
175-
176-
题中指出,**不需要保留节点的相对位置**
177-
178-
1. 遍历链表。
179-
2. 当节点符合小于 `x` 条件时,将其移动至头节点前方,成为新的头节点。
180-
3. 忽略大于等于 `x` 的节点。
181-
182206
<!-- end -->

0 commit comments

Comments
 (0)