Skip to content

Commit 3aff15b

Browse files
authored
feat: add solutions to lcci problem: No.02.01 (#2305)
No.02.01.Remove Duplicate Node
1 parent 7081216 commit 3aff15b

File tree

9 files changed

+217
-251
lines changed

9 files changed

+217
-251
lines changed

lcci/02.01.Remove Duplicate Node/README.md

+76-84
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,17 @@
3434

3535
## 解法
3636

37-
### 方法一
37+
### 方法一:哈希表
38+
39+
我们创建一个哈希表 $vis$,用于记录已经访问过的节点的值。
40+
41+
然后我们创建一个虚拟节点 $pre$,使得 $pre.next = head$。
42+
43+
接下来我们遍历链表,如果当前节点的值已经在哈希表中,我们就将当前节点删除,即 $pre.next = pre.next.next$;否则,我们将当前节点的值加入哈希表中,并将 $pre$ 指向下一个节点。
44+
45+
遍历结束后,我们返回链表的头节点。
46+
47+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为链表的长度。
3848

3949
<!-- tabs:start -->
4050

@@ -48,18 +58,14 @@
4858

4959
class Solution:
5060
def removeDuplicateNodes(self, head: ListNode) -> ListNode:
51-
if head is None or head.next is None:
52-
return head
53-
cache = set()
54-
cache.add(head.val)
55-
cur, p = head, head.next
56-
while p:
57-
if p.val not in cache:
58-
cur.next = p
59-
cur = cur.next
60-
cache.add(p.val)
61-
p = p.next
62-
cur.next = None
61+
vis = set()
62+
pre = ListNode(0, head)
63+
while pre.next:
64+
if pre.next.val in vis:
65+
pre.next = pre.next.next
66+
else:
67+
vis.add(pre.next.val)
68+
pre = pre.next
6369
return head
6470
```
6571

@@ -74,20 +80,15 @@ class Solution:
7480
*/
7581
class Solution {
7682
public ListNode removeDuplicateNodes(ListNode head) {
77-
if (head == null || head.next == null) {
78-
return head;
79-
}
80-
Set<Integer> s = new HashSet<>();
81-
s.add(head.val);
82-
ListNode cur = head;
83-
for (ListNode p = head.next; p != null; p = p.next) {
84-
if (!s.contains(p.val)) {
85-
cur.next = p;
86-
cur = cur.next;
87-
s.add(p.val);
83+
Set<Integer> vis = new HashSet<>();
84+
ListNode pre = new ListNode(0, head);
85+
while (pre.next != null) {
86+
if (vis.add(pre.next.val)) {
87+
pre = pre.next;
88+
} else {
89+
pre.next = pre.next.next;
8890
}
8991
}
90-
cur.next = null;
9192
return head;
9293
}
9394
}
@@ -105,37 +106,38 @@ class Solution {
105106
class Solution {
106107
public:
107108
ListNode* removeDuplicateNodes(ListNode* head) {
108-
if (head == nullptr || head->next == nullptr) {
109-
return head;
110-
}
111-
unordered_set<int> cache = {head->val};
112-
ListNode* cur = head;
113-
for (ListNode* p = head->next; p != nullptr; p = p->next) {
114-
if (!cache.count(p->val)) {
115-
cur->next = p;
116-
cur = cur->next;
117-
cache.insert(p->val);
109+
unordered_set<int> vis;
110+
ListNode* pre = new ListNode(0, head);
111+
while (pre->next) {
112+
if (vis.count(pre->next->val)) {
113+
pre->next = pre->next->next;
114+
} else {
115+
vis.insert(pre->next->val);
116+
pre = pre->next;
118117
}
119118
}
120-
cur->next = nullptr;
121119
return head;
122120
}
123121
};
124122
```
125123
126124
```go
125+
/**
126+
* Definition for singly-linked list.
127+
* type ListNode struct {
128+
* Val int
129+
* Next *ListNode
130+
* }
131+
*/
127132
func removeDuplicateNodes(head *ListNode) *ListNode {
128-
if head == nil {
129-
return nil
130-
}
131-
vis := map[int]bool{head.Val: true}
132-
p := head
133-
for p.Next != nil {
134-
if vis[p.Next.Val] {
135-
p.Next = p.Next.Next
133+
vis := map[int]bool{}
134+
pre := &ListNode{0, head}
135+
for pre.Next != nil {
136+
if vis[pre.Next.Val] {
137+
pre.Next = pre.Next.Next
136138
} else {
137-
vis[p.Next.Val] = true
138-
p = p.Next
139+
vis[pre.Next.Val] = true
140+
pre = pre.Next
139141
}
140142
}
141143
return head
@@ -156,17 +158,14 @@ func removeDuplicateNodes(head *ListNode) *ListNode {
156158
*/
157159

158160
function removeDuplicateNodes(head: ListNode | null): ListNode | null {
159-
if (head == null) {
160-
return head;
161-
}
162-
const set = new Set<number>([head.val]);
163-
let cur = head;
164-
while (cur.next != null) {
165-
if (set.has(cur.next.val)) {
166-
cur.next = cur.next.next;
161+
const vis: Set<number> = new Set();
162+
let pre: ListNode = new ListNode(0, head);
163+
while (pre.next) {
164+
if (vis.has(pre.next.val)) {
165+
pre.next = pre.next.next;
167166
} else {
168-
set.add(cur.next.val);
169-
cur = cur.next;
167+
vis.add(pre.next.val);
168+
pre = pre.next;
170169
}
171170
}
172171
return head;
@@ -193,24 +192,21 @@ function removeDuplicateNodes(head: ListNode | null): ListNode | null {
193192
use std::collections::HashSet;
194193

195194
impl Solution {
196-
pub fn remove_duplicate_nodes(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
197-
match head {
198-
None => head,
199-
Some(mut head) => {
200-
let mut set = HashSet::new();
201-
set.insert(head.val);
202-
let mut pre = &mut head;
203-
while let Some(cur) = &pre.next {
204-
if set.contains(&cur.val) {
205-
pre.next = pre.next.take().unwrap().next;
206-
} else {
207-
set.insert(cur.val);
208-
pre = pre.next.as_mut().unwrap();
209-
}
210-
}
211-
Some(head)
195+
pub fn remove_duplicate_nodes(mut head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
196+
let mut vis = HashSet::new();
197+
let mut pre = ListNode::new(0);
198+
pre.next = head;
199+
let mut cur = &mut pre;
200+
while let Some(node) = cur.next.take() {
201+
if vis.contains(&node.val) {
202+
cur.next = node.next;
203+
} else {
204+
vis.insert(node.val);
205+
cur.next = Some(node);
206+
cur = cur.next.as_mut().unwrap();
212207
}
213208
}
209+
pre.next
214210
}
215211
}
216212
```
@@ -228,20 +224,16 @@ impl Solution {
228224
* @return {ListNode}
229225
*/
230226
var removeDuplicateNodes = function (head) {
231-
if (head == null || head.next == null) return head;
232-
const cache = new Set([]);
233-
cache.add(head.val);
234-
let cur = head,
235-
fast = head.next;
236-
while (fast !== null) {
237-
if (!cache.has(fast.val)) {
238-
cur.next = fast;
239-
cur = cur.next;
240-
cache.add(fast.val);
227+
const vis = new Set();
228+
let pre = new ListNode(0, head);
229+
while (pre.next) {
230+
if (vis.has(pre.next.val)) {
231+
pre.next = pre.next.next;
232+
} else {
233+
vis.add(pre.next.val);
234+
pre = pre.next;
241235
}
242-
fast = fast.next;
243236
}
244-
cur.next = null;
245237
return head;
246238
};
247239
```

0 commit comments

Comments
 (0)