O(1) Insert Delete and Random Access Set
Problem
Design a set that supports three operations in O(1) expected time: insert(v), remove(v), and getRandom() which returns one of the stored values uniformly at random. The trick is to keep the values in a dense array (indexable for getRandom) plus a hash map from value to its array index. To delete, swap the value to the array's tail and pop it — that keeps the array dense and only touches two map entries.
Operations
insert(1), insert(2), insert(3), remove(2), getRandom()After
arr = [1, 3], idx = {1:0, 3:1}remove(2) overwrites slot 1 with the array's last value 3, then shrinks the array.
import random
class RandomizedSet:
def __init__(self):
self.arr = []
self.idx = {}
def insert(self, v):
if v in self.idx: return False
self.idx[v] = len(self.arr)
self.arr.append(v)
return True
def remove(self, v):
if v not in self.idx: return False
i = self.idx[v]
last = self.arr[-1]
self.arr[i] = last
self.idx[last] = i
self.arr.pop()
del self.idx[v]
return True
def getRandom(self):
return random.choice(self.arr)
class RandomizedSet {
constructor() { this.arr = []; this.idx = new Map(); }
insert(v) {
if (this.idx.has(v)) return false;
this.idx.set(v, this.arr.length);
this.arr.push(v);
return true;
}
remove(v) {
if (!this.idx.has(v)) return false;
const i = this.idx.get(v), last = this.arr[this.arr.length - 1];
this.arr[i] = last; this.idx.set(last, i);
this.arr.pop(); this.idx.delete(v);
return true;
}
getRandom() {
return this.arr[Math.floor(Math.random() * this.arr.length)];
}
}
class RandomizedSet {
List<Integer> arr = new ArrayList<>();
Map<Integer, Integer> idx = new HashMap<>();
Random rng = new Random();
public boolean insert(int v) {
if (idx.containsKey(v)) return false;
idx.put(v, arr.size());
arr.add(v);
return true;
}
public boolean remove(int v) {
Integer i = idx.get(v);
if (i == null) return false;
int last = arr.get(arr.size() - 1);
arr.set(i, last);
idx.put(last, i);
arr.remove(arr.size() - 1);
idx.remove(v);
return true;
}
public int getRandom() {
return arr.get(rng.nextInt(arr.size()));
}
}
class RandomizedSet {
vector<int> arr;
unordered_map<int, int> idx;
public:
bool insert(int v) {
if (idx.count(v)) return false;
idx[v] = arr.size();
arr.push_back(v);
return true;
}
bool remove(int v) {
auto it = idx.find(v);
if (it == idx.end()) return false;
int i = it->second, last = arr.back();
arr[i] = last;
idx[last] = i;
arr.pop_back();
idx.erase(it);
return true;
}
int getRandom() {
return arr[rand() % arr.size()];
}
};