Design HashSet
The drill: Build a set of non-negative integers from scratch — add, remove, and check membership — without reaching for a language's built-in hash set.
A set of non-negative integers needs building from the ground up — add a value, remove a value, and check whether a value is currently present — without leaning on a language's ready-made hash set.
Adding a value already inside does nothing new, and removing a value that isn't present is simply a no-op; the set only ever tracks presence, never how many times something was added.
This site drives the drill as a sequence of operations against one live instance: each call acts on whatever the set currently holds, in the order the calls arrive.
- keys are non-negative integers within a bounded, modest range
- add on an existing key and remove on a missing key are both harmless no-ops
- operations are processed one at a time, in arrival order
- no built-in hash set or map type may back the implementation
HINT 1 THE NUDGE
A plain list gets add and remove for free, but membership means scanning every element. How do you make 'have I seen this' stop depending on how many things you've stored?
HINT 2 THE STRUCTURE
Keys live in a bounded range. A fixed-size array of buckets, indexed by key modulo the bucket count, turns 'which bucket' into one division.
HINT 3 ONE STEP FROM THE ANSWER
Each bucket only ever holds the handful of keys that collide into it — a short list per bucket, scanned only within that bucket, keeps every operation close to O(1).
Ops run against one live set, hashed into fixed buckets by key mod table size.
class MyHashSet:
def __init__(self):
self.buckets = 1000
self.table = [[] for _ in range(self.buckets)]
def _bucket(self, key: int) -> list:
return self.table[key % self.buckets]
def add(self, key: int) -> None:
bucket = self._bucket(key)
if key not in bucket:
bucket.append(key)
def remove(self, key: int) -> None:
bucket = self._bucket(key)
if key in bucket:
bucket.remove(key)
def contains(self, key: int) -> bool:
return key in self._bucket(key)class MyHashSet:
def __init__(self):
self.items = []
def add(self, key: int) -> None:
if key not in self.items:
self.items.append(key)
def remove(self, key: int) -> None:
if key in self.items:
self.items.remove(key)
def contains(self, key: int) -> bool:
return key in self.itemsclass MyHashSet {
private final List<Integer>[] table;
private final int buckets = 1000;
public MyHashSet() {
table = new List[buckets];
for (int i = 0; i < buckets; i++) {
table[i] = new ArrayList<>();
}
}
public void add(int key) {
List<Integer> bucket = table[key % buckets];
if (!bucket.contains(key)) {
bucket.add(key);
}
}
public void remove(int key) {
table[key % buckets].remove(Integer.valueOf(key));
}
public boolean contains(int key) {
return table[key % buckets].contains(key);
}
}class MyHashSet {
private final List<Integer> items = new ArrayList<>();
public MyHashSet() {
}
public void add(int key) {
if (!items.contains(key)) {
items.add(key);
}
}
public void remove(int key) {
items.remove(Integer.valueOf(key));
}
public boolean contains(int key) {
return items.contains(key);
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED