Skip to content

Commit 6e55116

Browse files
committed
feat: add solutions to lcof2 problems: No.030,031
1 parent 4b378a0 commit 6e55116

File tree

6 files changed

+563
-10
lines changed

6 files changed

+563
-10
lines changed

lcof2/剑指 Offer II 030. 插入、删除和随机访问都是 O(1) 的容器/README.md

+102-9
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@
2424
</strong>RandomizedSet randomSet = new RandomizedSet(); // 初始化一个空的集合
2525
randomSet.insert(1); // 向集合中插入 1 , 返回 true 表示 1 被成功地插入
2626

27-
randomSet.remove(2); // 返回 false,表示集合中不存在 2
27+
randomSet.remove(2); // 返回 false,表示集合中不存在 2
2828

29-
randomSet.insert(2); // 向集合中插入 2 返回 true ,集合现在包含 [1,2]
29+
randomSet.insert(2); // 向集合中插入 2 返回 true ,集合现在包含 [1,2]
3030

31-
randomSet.getRandom(); // getRandom 应随机返回 1 或 2
32-
33-
randomSet.remove(1); // 从集合中移除 1 返回 true 。集合现在包含 [2]
31+
randomSet.getRandom(); // getRandom 应随机返回 1 或 2
3432

35-
randomSet.insert(2); // 2 已在集合中,所以返回 false
33+
randomSet.remove(1); // 从集合中移除 1 返回 true 。集合现在包含 [2]
3634

37-
randomSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2
35+
randomSet.insert(2); // 2 已在集合中,所以返回 false
36+
37+
randomSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2
3838
</pre>
3939

4040
<p>&nbsp;</p>
@@ -56,22 +56,115 @@ randomSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
“哈希表 + 动态列表”实现。
60+
61+
哈希表存放每个元素的值和对应的下标,而动态列表在每个下标位置存放每个元素。由动态列表实现元素的随机返回。
62+
63+
注意,在 `remove()` 实现上,将列表的最后一个元素设置到待删元素的位置上,然后删除最后一个元素,这样在删除元素的时候,不需要挪动一大批元素,从而实现 `O(1)` 时间内操作。
64+
5965
<!-- tabs:start -->
6066

6167
### **Python3**
6268

6369
<!-- 这里可写当前语言的特殊实现逻辑 -->
6470

6571
```python
66-
72+
class RandomizedSet:
73+
def __init__(self):
74+
"""
75+
Initialize your data structure here.
76+
"""
77+
self.a = []
78+
self.m = {}
79+
80+
def insert(self, val: int) -> bool:
81+
"""
82+
Inserts a value to the set. Returns true if the set did not already contain the specified element.
83+
"""
84+
if val in self.m:
85+
return False
86+
self.m[val] = len(self.a)
87+
self.a.append(val)
88+
return True
89+
90+
def remove(self, val: int) -> bool:
91+
"""
92+
Removes a value from the set. Returns true if the set contained the specified element.
93+
"""
94+
if val in self.m:
95+
idx = self.m[val]
96+
self.a[idx], self.a[-1] = self.a[-1], self.a[idx]
97+
self.m[self.a[idx]] = idx
98+
self.a.pop()
99+
del self.m[val]
100+
return True
101+
return False
102+
103+
def getRandom(self) -> int:
104+
"""
105+
Get a random element from the set.
106+
"""
107+
return random.choice(self.a)
108+
109+
110+
# Your RandomizedSet object will be instantiated and called as such:
111+
# obj = RandomizedSet()
112+
# param_1 = obj.insert(val)
113+
# param_2 = obj.remove(val)
114+
# param_3 = obj.getRandom()
67115
```
68116

69117
### **Java**
70118

71119
<!-- 这里可写当前语言的特殊实现逻辑 -->
72120

73121
```java
74-
122+
class RandomizedSet {
123+
private final Map<Integer, Integer> m;
124+
private final List<Integer> a;
125+
126+
/** Initialize your data structure here. */
127+
public RandomizedSet() {
128+
this.m = new HashMap<>();
129+
this.a = new ArrayList<>();
130+
}
131+
132+
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
133+
public boolean insert(int val) {
134+
if (this.m.containsKey(val)) {
135+
return false;
136+
}
137+
this.m.put(val, this.a.size());
138+
this.a.add(val);
139+
return true;
140+
}
141+
142+
/** Removes a value from the set. Returns true if the set contained the specified element. */
143+
public boolean remove(int val) {
144+
if (this.m.containsKey(val)) {
145+
int idx = this.m.get(val), last = this.a.size() - 1;
146+
Collections.swap(this.a, idx, last);
147+
this.m.put(this.a.get(idx), idx);
148+
this.a.remove(last);
149+
this.m.remove(val);
150+
return true;
151+
}
152+
return false;
153+
}
154+
155+
/** Get a random element from the set. */
156+
public int getRandom() {
157+
return this.a.get(ThreadLocalRandom.current().nextInt(this.a.size()));
158+
}
159+
}
160+
161+
/**
162+
* Your RandomizedSet object will be instantiated and called as such:
163+
* RandomizedSet obj = new RandomizedSet();
164+
* boolean param_1 = obj.insert(val);
165+
* boolean param_2 = obj.remove(val);
166+
* int param_3 = obj.getRandom();
167+
*/
75168
```
76169

77170
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class RandomizedSet {
2+
private final Map<Integer, Integer> m;
3+
private final List<Integer> a;
4+
5+
/** Initialize your data structure here. */
6+
public RandomizedSet() {
7+
this.m = new HashMap<>();
8+
this.a = new ArrayList<>();
9+
}
10+
11+
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
12+
public boolean insert(int val) {
13+
if (this.m.containsKey(val)) {
14+
return false;
15+
}
16+
this.m.put(val, this.a.size());
17+
this.a.add(val);
18+
return true;
19+
}
20+
21+
/** Removes a value from the set. Returns true if the set contained the specified element. */
22+
public boolean remove(int val) {
23+
if (this.m.containsKey(val)) {
24+
int idx = this.m.get(val), last = this.a.size() - 1;
25+
Collections.swap(this.a, idx, last);
26+
this.m.put(this.a.get(idx), idx);
27+
this.a.remove(last);
28+
this.m.remove(val);
29+
return true;
30+
}
31+
return false;
32+
}
33+
34+
/** Get a random element from the set. */
35+
public int getRandom() {
36+
return this.a.get(ThreadLocalRandom.current().nextInt(this.a.size()));
37+
}
38+
}
39+
40+
/**
41+
* Your RandomizedSet object will be instantiated and called as such:
42+
* RandomizedSet obj = new RandomizedSet();
43+
* boolean param_1 = obj.insert(val);
44+
* boolean param_2 = obj.remove(val);
45+
* int param_3 = obj.getRandom();
46+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
class RandomizedSet:
2+
def __init__(self):
3+
"""
4+
Initialize your data structure here.
5+
"""
6+
self.a = []
7+
self.m = {}
8+
9+
def insert(self, val: int) -> bool:
10+
"""
11+
Inserts a value to the set. Returns true if the set did not already contain the specified element.
12+
"""
13+
if val in self.m:
14+
return False
15+
self.m[val] = len(self.a)
16+
self.a.append(val)
17+
return True
18+
19+
def remove(self, val: int) -> bool:
20+
"""
21+
Removes a value from the set. Returns true if the set contained the specified element.
22+
"""
23+
if val in self.m:
24+
idx = self.m[val]
25+
self.a[idx], self.a[-1] = self.a[-1], self.a[idx]
26+
self.m[self.a[idx]] = idx
27+
self.a.pop()
28+
del self.m[val]
29+
return True
30+
return False
31+
32+
def getRandom(self) -> int:
33+
"""
34+
Get a random element from the set.
35+
"""
36+
return random.choice(self.a)
37+
38+
39+
# Your RandomizedSet object will be instantiated and called as such:
40+
# obj = RandomizedSet()
41+
# param_1 = obj.insert(val)
42+
# param_2 = obj.remove(val)
43+
# param_3 = obj.getRandom()

0 commit comments

Comments
 (0)