Skip to content

Commit 5dad83b

Browse files
committed
一刷705
1 parent e62ce5f commit 5dad83b

File tree

6 files changed

+191
-38
lines changed

6 files changed

+191
-38
lines changed

README.adoc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,13 +4961,13 @@ TIP: **公众号的微信号是: `jikerizhi`**。__因为众所周知的原因
49614961
|Easy
49624962
|
49634963

4964-
//|{counter:codes}
4965-
//|{leetcode_base_url}/design-hashset/[705. Design HashSet^]
4966-
//|{source_base_url}/_0705_DesignHashSet.java[Java]
4967-
//|{doc_base_url}/0705-design-hashset.adoc[题解]
4968-
//|Easy
4969-
//|
4970-
//
4964+
|{counter:codes}
4965+
|{leetcode_base_url}/design-hashset/[705. Design HashSet^]
4966+
|{source_base_url}/_0705_DesignHashSet.java[Java]
4967+
|{doc_base_url}/0705-design-hashset.adoc[题解]
4968+
|Easy
4969+
|
4970+
49714971
//|{counter:codes}
49724972
//|{leetcode_base_url}/design-hashmap/[706. Design HashMap^]
49734973
//|{source_base_url}/_0706_DesignHashMap.java[Java]

docs/0705-design-hashset.adoc

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,81 @@
11
[#0705-design-hashset]
2-
= 705. Design HashSet
2+
= 705. 设计哈希集合
33

4-
{leetcode}/problems/design-hashset/[LeetCode - Design HashSet^]
4+
https://leetcode.cn/problems/design-hashset/[LeetCode - 705. 设计哈希集合 ^]
55

6-
Design a HashSet without using any built-in hash table libraries.
6+
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
77

8-
To be specific, your design should include these functions:
8+
实现 `MyHashSet` 类:
99

10+
* `void add(key)` 向哈希集合中插入值 `key`
11+
* `bool contains(key)` 返回哈希集合中是否存在这个值 `key`
12+
* `void remove(key)` 将给定值 `key`
13+
从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
1014
11-
* `add(value)`: Insert a value into the HashSet.
12-
* `contains(value)` : Return whether the value exists in the HashSet or not.
13-
* `remove(value)`: Remove a value in the HashSet. If the value does not exist in the HashSet, do nothing.
1415
16+
*示例:*
1517

18+
....
19+
输入:
20+
["MyHashSet", "add", "add", "contains", "contains", "add", "contains", "remove", "contains"]
21+
[[], [1], [2], [1], [3], [2], [2], [2], [2]]
22+
输出:
23+
[null, null, null, true, false, null, true, null, false]
1624
25+
解释:
26+
MyHashSet myHashSet = new MyHashSet();
27+
myHashSet.add(1); // set = [1]
28+
myHashSet.add(2); // set = [1, 2]
29+
myHashSet.contains(1); // 返回 True
30+
myHashSet.contains(3); // 返回 False ,(未找到)
31+
myHashSet.add(2); // set = [1, 2]
32+
myHashSet.contains(2); // 返回 True
33+
myHashSet.remove(2); // set = [1]
34+
myHashSet.contains(2); // 返回 False ,(已移除)
35+
....
1736

37+
*提示:*
1838

19-
*Example:*
39+
* `0 \<= key \<= 10^6^`
40+
* 最多调用 `10^4^``add``remove``contains`
2041
21-
[subs="verbatim,quotes,macros"]
22-
----
23-
MyHashSet hashSet = new MyHashSet();
24-
hashSet.add(1);
25-
hashSet.add(2);
26-
hashSet.contains(1); // returns true
27-
hashSet.contains(3); // returns false (not found)
28-
hashSet.add(2);
29-
hashSet.contains(2); // returns true
30-
hashSet.remove(2);
31-
hashSet.contains(2); // returns false (already removed)
32-
----
33-
34-
35-
36-
37-
*Note:*
3842
43+
== 思路分析
3944

40-
* All values will be in the range of `[0, 1000000]`.
41-
* The number of operations will be in the range of `[1, 10000]`.
42-
* Please do not use the built-in HashSet library.
43-
45+
三种解决冲突的办法:
4446

47+
. 拉链法
48+
. 开放地址法
49+
. 再哈希法
4550

51+
image::images/0705-01.png[{image_attr}]
4652

4753
[[src-0705]]
54+
[tabs]
55+
====
56+
一刷::
57+
+
58+
--
4859
[{java_src_attr}]
4960
----
50-
include::{sourcedir}/_0705_DesignHashSet.java[tag=answer]
61+
include::{sourcedir}/_0705_DesignHashset.java[tag=answer]
5162
----
63+
--
64+
65+
// 二刷::
66+
// +
67+
// --
68+
// [{java_src_attr}]
69+
// ----
70+
// include::{sourcedir}/_0705_DesignHashset_2.java[tag=answer]
71+
// ----
72+
// --
73+
====
74+
75+
76+
== 参考资料
77+
78+
. https://leetcode.cn/problems/design-hashset/solutions/652778/she-ji-ha-xi-ji-he-by-leetcode-solution-xp4t/[705. 设计哈希集合 - 官方题解^]
79+
. https://leetcode.cn/problems/design-hashset/solutions/653252/xiang-jie-hashset-de-she-ji-zai-shi-jian-4plc/[705. 设计哈希集合 - 详解 HashSet 的设计:在时间和空间上做权衡^]
80+
. https://leetcode.cn/problems/design-hashset/solutions/653184/yi-ti-san-jie-jian-dan-shu-zu-lian-biao-nj3dg/[705. 设计哈希集合 - 【宫水三叶】一题三解:「简单数组」&「链表」& 「分桶数组」^]
5281

docs/images/0705-01.png

119 KB
Loading

docs/index.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ include::0701-insert-into-a-binary-search-tree.adoc[leveloffset=+1]
14941494

14951495
include::0704-binary-search.adoc[leveloffset=+1]
14961496

1497-
// include::0705-design-hashset.adoc[leveloffset=+1]
1497+
include::0705-design-hashset.adoc[leveloffset=+1]
14981498

14991499
// include::0706-design-hashmap.adoc[leveloffset=+1]
15001500

logbook/202503.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,11 @@ endif::[]
643643
|{doc_base_url}/3115-maximum-prime-difference.adoc[题解]
644644
|✅ 质数判断
645645

646+
|{counter:codes2503}
647+
|{leetcode_base_url}/design-hashset/[705. 设计哈希集合^]
648+
|{doc_base_url}/0705-design-hashset.adoc[题解]
649+
|✅ 使用开放地址法解决哈希冲突。
650+
646651
|===
647652

648653
截止目前,本轮练习一共完成 {codes2503} 道题。
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.Arrays;
4+
5+
public class _0705_DesignHashset {
6+
// tag::answer[]
7+
8+
/**
9+
* @author D瓜哥 · https://www.diguage.com
10+
* @since 2025-05-10 19:50:48
11+
*/
12+
class MyHashSet {
13+
private int[] data;
14+
private int mask;
15+
private int size;
16+
17+
public MyHashSet() {
18+
data = new int[8];
19+
Arrays.fill(data, -1);
20+
mask = 8 - 1;
21+
size = 0;
22+
}
23+
24+
public void add(int key) {
25+
if (size >= data.length * 3 / 4) {
26+
resize(data.length * 2);
27+
}
28+
boolean result = add(data, key, mask);
29+
if (result) {
30+
size++;
31+
}
32+
}
33+
34+
public void remove(int key) {
35+
int index = key & mask;
36+
boolean ok = false;
37+
for (int i = index; i < data.length; i++) {
38+
if (data[i] == key) {
39+
data[i] = -1;
40+
ok = true;
41+
}
42+
}
43+
if (!ok) {
44+
for (int i = 0; i < index; i++) {
45+
if (data[i] == key) {
46+
data[i] = -1;
47+
ok = true;
48+
}
49+
}
50+
}
51+
if (ok) {
52+
size--;
53+
}
54+
// 需要考虑在初始化时,没有值的情况的缩容问题
55+
if (size <= data.length / 3 && data.length > 8) {
56+
resize(data.length / 2);
57+
}
58+
}
59+
60+
public boolean contains(int key) {
61+
int index = key & mask;
62+
for (int i = index; i < data.length; i++) {
63+
if (data[i] == key) {
64+
return true;
65+
}
66+
}
67+
for (int i = 0; i < index; i++) {
68+
if (data[i] == key) {
69+
return true;
70+
}
71+
}
72+
return false;
73+
}
74+
75+
private void resize(int length) {
76+
int[] newData = new int[length];
77+
Arrays.fill(newData, -1);
78+
int newMask = length - 1;
79+
for (int k : data) {
80+
if (k == -1) {
81+
continue;
82+
}
83+
add(newData, k, newMask);
84+
}
85+
this.data = newData;
86+
this.mask = newMask;
87+
}
88+
89+
private boolean add(int[] data, int key, int newMask) {
90+
int index = key & newMask;
91+
if (data[index] == -1) {
92+
data[index] = key;
93+
return true;
94+
} else if (data[index] == key) {
95+
return false;
96+
} else {
97+
// 使用开放地址法解决哈希冲突
98+
for (int j = index + 1; j < data.length; j++) {
99+
if (data[j] == -1) {
100+
data[j] = key;
101+
return true;
102+
} else if (data[j] == key) {
103+
return false;
104+
}
105+
}
106+
for (int j = 0; j < index; j++) {
107+
if (data[j] == -1) {
108+
data[j] = key;
109+
return true;
110+
} else if (data[j] == key) {
111+
return false;
112+
}
113+
}
114+
}
115+
return false;
116+
}
117+
}
118+
// end::answer[]
119+
}

0 commit comments

Comments
 (0)