Skip to content

Commit cdb8bca

Browse files
authored
feat: add solutions to lc/lcof2 problems (#640)
lcof2 No.030 & lc 0380.Insert Delete GetRandom O(1)
1 parent fd779b2 commit cdb8bca

File tree

5 files changed

+253
-0
lines changed

5 files changed

+253
-0
lines changed

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

+60
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,66 @@ class RandomizedSet {
167167
*/
168168
```
169169

170+
### **C++**
171+
172+
1. 插入
173+
174+
每次添加新数值时,先使用哈希表判断该数值是否存在,存在则直接返回false。不存在则进行插入操作,只要将该数值添加到数组尾部即可,并将该数值和其下标的映射存入哈希表。
175+
176+
2. 删除
177+
178+
删除同样需使用哈希表判断是否存在,若不存在则返回false。存在则进行删除操作,在哈希表中删除时间复杂度为 O(1),但是在数值中删除比较麻烦。若只是直接删除,则为了保证数组内存连续性需将删除数值后面的数值均前移一位,时间复杂度为 O(n)。比较好的处理方式是,用数组的最后一个数值去填充需要删除的数值的内存,其他数值在数组中的位置保持不变,并将这个拿来填充的数值的下标更新即可,最后只要删除数组最后一个数值,同样可以保证时间复杂度为 O(1)。
179+
180+
3. 随机返回
181+
182+
只要随机生成数组下标范围内一个随机下标值,返回该数组下标内的数值即可。
183+
184+
185+
```cpp
186+
class RandomizedSet {
187+
unordered_map<int, int> mp;
188+
vector<int> nums;
189+
public:
190+
RandomizedSet() {
191+
192+
}
193+
194+
bool insert(int val) {
195+
if (mp.count(val))
196+
return false;
197+
198+
mp[val] = nums.size();
199+
nums.push_back(val);
200+
return true;
201+
}
202+
203+
bool remove(int val) {
204+
if (!mp.count(val))
205+
return false;
206+
207+
int removeIndex = mp[val];
208+
nums[removeIndex] = nums.back();
209+
mp[nums.back()] = removeIndex;
210+
211+
mp.erase(val);
212+
nums.pop_back();
213+
return true;
214+
}
215+
216+
int getRandom() {
217+
return nums[rand() % nums.size()];
218+
}
219+
};
220+
221+
/**
222+
* Your RandomizedSet object will be instantiated and called as such:
223+
* RandomizedSet* obj = new RandomizedSet();
224+
* bool param_1 = obj->insert(val);
225+
* bool param_2 = obj->remove(val);
226+
* int param_3 = obj->getRandom();
227+
*/
228+
```
229+
170230
### **...**
171231
172232
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
class RandomizedSet {
2+
unordered_map<int, int> mp;
3+
vector<int> nums;
4+
public:
5+
RandomizedSet() {
6+
7+
}
8+
9+
bool insert(int val) {
10+
if (mp.count(val))
11+
return false;
12+
13+
mp[val] = nums.size();
14+
nums.push_back(val);
15+
return true;
16+
}
17+
18+
bool remove(int val) {
19+
if (!mp.count(val))
20+
return false;
21+
22+
int removeIndex = mp[val];
23+
nums[removeIndex] = nums.back();
24+
mp[nums.back()] = removeIndex;
25+
26+
mp.erase(val);
27+
nums.pop_back();
28+
return true;
29+
}
30+
31+
int getRandom() {
32+
return nums[rand() % nums.size()];
33+
}
34+
};
35+
36+
/**
37+
* Your RandomizedSet object will be instantiated and called as such:
38+
* RandomizedSet* obj = new RandomizedSet();
39+
* bool param_1 = obj->insert(val);
40+
* bool param_2 = obj->remove(val);
41+
* int param_3 = obj->getRandom();
42+
*/

solution/0300-0399/0380.Insert Delete GetRandom O(1)/README.md

+60
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,66 @@ class RandomizedSet {
163163
*/
164164
```
165165

166+
### **C++**
167+
168+
1. 插入
169+
170+
每次添加新数值时,先使用哈希表判断该数值是否存在,存在则直接返回false。不存在则进行插入操作,只要将该数值添加到数组尾部即可,并将该数值和其下标的映射存入哈希表。
171+
172+
2. 删除
173+
174+
删除同样需使用哈希表判断是否存在,若不存在则返回false。存在则进行删除操作,在哈希表中删除时间复杂度为 O(1),但是在数值中删除比较麻烦。若只是直接删除,则为了保证数组内存连续性需将删除数值后面的数值均前移一位,时间复杂度为 O(n)。比较好的处理方式是,用数组的最后一个数值去填充需要删除的数值的内存,其他数值在数组中的位置保持不变,并将这个拿来填充的数值的下标更新即可,最后只要删除数组最后一个数值,同样可以保证时间复杂度为 O(1)。
175+
176+
3. 随机返回
177+
178+
只要随机生成数组下标范围内一个随机下标值,返回该数组下标内的数值即可。
179+
180+
181+
```cpp
182+
class RandomizedSet {
183+
unordered_map<int, int> mp;
184+
vector<int> nums;
185+
public:
186+
RandomizedSet() {
187+
188+
}
189+
190+
bool insert(int val) {
191+
if (mp.count(val))
192+
return false;
193+
194+
mp[val] = nums.size();
195+
nums.push_back(val);
196+
return true;
197+
}
198+
199+
bool remove(int val) {
200+
if (!mp.count(val))
201+
return false;
202+
203+
int removeIndex = mp[val];
204+
nums[removeIndex] = nums.back();
205+
mp[nums.back()] = removeIndex;
206+
207+
mp.erase(val);
208+
nums.pop_back();
209+
return true;
210+
}
211+
212+
int getRandom() {
213+
return nums[rand() % nums.size()];
214+
}
215+
};
216+
217+
/**
218+
* Your RandomizedSet object will be instantiated and called as such:
219+
* RandomizedSet* obj = new RandomizedSet();
220+
* bool param_1 = obj->insert(val);
221+
* bool param_2 = obj->remove(val);
222+
* int param_3 = obj->getRandom();
223+
*/
224+
```
225+
166226
### **...**
167227
168228
```

solution/0300-0399/0380.Insert Delete GetRandom O(1)/README_EN.md

+48
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,54 @@ class RandomizedSet {
155155
*/
156156
```
157157

158+
### **C++**
159+
160+
```cpp
161+
class RandomizedSet {
162+
unordered_map<int, int> mp;
163+
vector<int> nums;
164+
public:
165+
RandomizedSet() {
166+
167+
}
168+
169+
bool insert(int val) {
170+
if (mp.count(val))
171+
return false;
172+
173+
mp[val] = nums.size();
174+
nums.push_back(val);
175+
return true;
176+
}
177+
178+
bool remove(int val) {
179+
if (!mp.count(val))
180+
return false;
181+
182+
int removeIndex = mp[val];
183+
nums[removeIndex] = nums.back();
184+
mp[nums.back()] = removeIndex;
185+
186+
mp.erase(val);
187+
nums.pop_back();
188+
return true;
189+
}
190+
191+
int getRandom() {
192+
return nums[rand() % nums.size()];
193+
}
194+
};
195+
196+
/**
197+
* Your RandomizedSet object will be instantiated and called as such:
198+
* RandomizedSet* obj = new RandomizedSet();
199+
* bool param_1 = obj->insert(val);
200+
* bool param_2 = obj->remove(val);
201+
* int param_3 = obj->getRandom();
202+
*/
203+
```
204+
```
205+
158206
### **...**
159207

160208
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
class RandomizedSet {
2+
unordered_map<int, int> mp;
3+
vector<int> nums;
4+
public:
5+
RandomizedSet() {
6+
7+
}
8+
9+
bool insert(int val) {
10+
if (mp.count(val))
11+
return false;
12+
13+
mp[val] = nums.size();
14+
nums.push_back(val);
15+
return true;
16+
}
17+
18+
bool remove(int val) {
19+
if (!mp.count(val))
20+
return false;
21+
22+
int removeIndex = mp[val];
23+
nums[removeIndex] = nums.back();
24+
mp[nums.back()] = removeIndex;
25+
26+
mp.erase(val);
27+
nums.pop_back();
28+
return true;
29+
}
30+
31+
int getRandom() {
32+
return nums[rand() % nums.size()];
33+
}
34+
};
35+
36+
/**
37+
* Your RandomizedSet object will be instantiated and called as such:
38+
* RandomizedSet* obj = new RandomizedSet();
39+
* bool param_1 = obj->insert(val);
40+
* bool param_2 = obj->remove(val);
41+
* int param_3 = obj->getRandom();
42+
*/
43+
```

0 commit comments

Comments
 (0)