380.Insert Delete GetRandom O(1)
===
###### tags: `Medium`,`Array`,`Hash Table`,`Math`
[380. Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1/)
### 題目描述
Implement the `RandomizedSet` class:
* `RandomizedSet()` Initializes the `RandomizedSet` object.
* `bool insert(int val)` Inserts an item `val` into the set if not present. Returns `true` if the item was not present, `false` otherwise.
* `bool remove(int val)` Removes an item `val` from the set if present. Returns `true` if the item was present, `false` otherwise.
* `int getRandom()` Returns a random element from the current set of elements (it's guaranteed that at least one element exists when this method is called). Each element must have the **same probability** of being returned.
You must implement the functions of the class such that each function works in **average** $O(1)$ time complexity.
### 範例
**Example 1:**
```
Input
["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
[[], [1], [2], [2], [], [1], [2], []]
Output
[null, true, false, true, 2, true, false, 2]
Explanation
RandomizedSet randomizedSet = new RandomizedSet();
randomizedSet.insert(1);
// Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomizedSet.remove(2);
// Returns false as 2 does not exist in the set.
randomizedSet.insert(2);
// Inserts 2 to the set, returns true. Set now contains [1,2].
randomizedSet.getRandom();
// getRandom() should return either 1 or 2 randomly.
randomizedSet.remove(1);
// Removes 1 from the set, returns true. Set now contains [2].
randomizedSet.insert(2);
// 2 was already in the set, so return false.
randomizedSet.getRandom();
// Since 2 is the only number in the set, getRandom() will always return 2.
```
**Constraints**:
* $-2^{31}$ <= `val` <= $2^{31} - 1$
* At most $2 * 10^5$ calls will be made to `insert`, `remove`, and `getRandom`.
* There will be at least one element in the data structure when `getRandom` is called.
### 解答
#### Python
```python=
from random import randint
class RandomizedSet:
def __init__(self):
self.ht = defaultdict(bool)
self.set = set()
def insert(self, val: int) -> bool:
if not self.ht[val]:
self.ht[val] = True
self.set.add(val)
return True
return False
def remove(self, val: int) -> bool:
if self.ht[val]:
self.ht[val] = False
self.set.remove(val)
return True
return False
def getRandom(self) -> int:
choose = randint(0, len(self.set) - 1)
return list(self.set)[choose]
# Your RandomizedSet object will be instantiated and called as such:
# obj = RandomizedSet()
# param_1 = obj.insert(val)
# param_2 = obj.remove(val)
# param_3 = obj.getRandom()
```
> [name=Kobe][time=Tue, Nov 29]
```python=
class RandomizedSet:
def __init__(self):
self.data = set()
def insert(self, val: int) -> bool:
if val in self.data:
return False
self.data.add(val)
return True
def remove(self, val: int) -> bool:
if val not in self.data:
return False
self.data.remove(val)
return True
def getRandom(self) -> int:
return sample(self.data, 1)[0]
```
> [name=Yen-Chi Chen][time=Tue, Nov 29, 2022]
#### C++
```cpp=
class RandomizedSet {
vector<int> data;
unordered_map<int, int> m;
public:
RandomizedSet() {
}
bool insert(int val) {
if (m.find(val) != m.end()) {
return false;
}
m[val] = data.size();
data.push_back(val);
return true;
}
bool remove(int val) {
if (m.find(val) != m.end()) {
data[m[val]] = data.back();
m[data.back()] = m[val];
data.pop_back();
m.erase(val);
return true;
}
return false;
}
int getRandom() {
return data[rand() % data.size()];
}
};
```
> [name=Yen-Chi Chen][time=Tue, Nov 29, 2022]
#### Javascript
```javascript=
class RandomizedSet {
constructor() {
this.map = new Map();
this.list = [];
}
insert(val) {
if (this.map.has(val)) return false;
this.map.set(val, this.list.length);
this.list.push(val);
return true;
}
remove(val) {
if (!this.map.has(val)) return false;
const index = this.map.get(val);
const last = this.list.pop();
if (index !== this.list.length) {
this.list[index] = last;
this.map.set(last, index);
}
this.map.delete(val);
return true;
}
getRandom() {
return this.list[~~(Math.random() * this.list.length)];
}
}
```
> [name=Marsgoat][time=Nov 29, 2022]
### Reference
[回到題目列表](https://hackmd.io/@Marsgoat/leetcode_every_day)