Design HashSet

Open-addressing or separate-chaining hash set — bucket by hash, linear list inside each bucket.

Easy
Time O(1) average per op Space O(n)
LeetCode
3 min read
design hash-set

Problem#

Implement MyHashSet with add, remove, contains — without using the built-in hash set.

Examples#

  • add(1); add(2); contains(1)true; contains(3)false.
  • add(2); remove(2); contains(2)false.

Constraints#

  • 0 <= key <= 10^6, up to 10^4 calls.

Approach#

Separate chaining. Fixed-size bucket array; each bucket is a list<int>. Hash by key % buckets. Linear scan within a bucket for membership.

Solution#

MyHashSet
class MyHashSet {
static const int B = 769; // prime
vector<list<int>> buckets;
list<int>::iterator findIt(int key, int idx) {
return find(buckets[idx].begin(), buckets[idx].end(), key);
}
public:
MyHashSet() : buckets(B) {}
void add(int key) {
int idx = key % B;
if (findIt(key, idx) == buckets[idx].end())
buckets[idx].push_back(key);
}
void remove(int key) {
int idx = key % B;
auto it = findIt(key, idx);
if (it != buckets[idx].end()) buckets[idx].erase(it);
}
bool contains(int key) {
int idx = key % B;
return findIt(key, idx) != buckets[idx].end();
}
};

Editorial#

A prime bucket count smooths the distribution if keys cluster on multiples of small numbers. Each bucket stays short (average n / B), so all ops are O(1) average.

Complexity#

  • Time: O(1) average.
  • Space: O(n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.