Design HashSet
Introduction
Design a HashSet without using any built-in hash table libraries.
Implement MyHashSet
-
Inserts the valuevoid add(key)
into the HashSet.key
-
Returns whether the valuebool contains(key)
exists in the HashSet or not.key
-
Removes the valuevoid remove(key)
in the HashSet. Ifkey
does not exist in the HashSet, do nothing.key
Example 1
values = [[], [1], [2], [1], [3], [2], [2], [2], [2]]
Output: [null, null, null, true, false, null, true, null, false]
Explanation:
myHashSet.add(1); // set = [1]
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(1); // return True
myHashSet.contains(3); // return False, (not found)
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(2); // return True
myHashSet.remove(2); // set = [1]
myHashSet.contains(2); // return False, (already removed)
Constraints:
0 <= key <= 106
- At most 104 calls will be made to
,add
, andremove
.contains
Solution 1 - Using an array of LinkedLists
In this approach, we will use an array of LinkedList
10000
In order to find the index where to insert a given key, we will do a modular operation on the key value with array length, this will ensure that we will never got out of bounds of array.
int hashIndex = key % array.length;
Implementation steps:
-
Constructor: we will initialize array elements with empty
, so that we don't need to doLinkedList
null
checks later. -
add(int key): we will get the index using
, then check if thekey % array.length
already in thekey
at that index or not, if it does not contain the key, then add it to the linked list.LinkedList
-
remove(int key): we will get the index using
, then remove the entry with thekey % array.length
from thekey
at that index.LinkedList
-
contains(int key): we will get the index using
, then check if the element is present in thekey % array.length
at that index. If it present returnLinkedList
,true
otherwise.false
import java.util.Arrays;
import java.util.LinkedList;
public class MyHashSet {
LinkedList<Integer>[] set = new LinkedList[10000]; // This can be changed as needed to spread numbers across
public MyHashSet() { // to avoid NPEs later, initializing with empty LinkedLists
for(int i=0;i< set.length; i++) {
set[i] = new LinkedList<>();
}
}
public void add(int key) {
if(!contains(key)) {
int hashKey = key % set.length;
set[hashKey].add(key);
}
}
public void remove(int key) {
int hashKey = key % set.length;
set[hashKey].remove(Integer.valueOf(key));
}
public boolean contains(int key) {
int hashKey = key % set.length;
return set[hashKey].contains(key);
}
public static void main(String[] args) {
MyHashSet myHashSet = new MyHashSet();
myHashSet.add(1);
myHashSet.add(2);
System.out.println(Arrays.toString(myHashSet.set));
System.out.println(myHashSet.contains(1));
System.out.println(myHashSet.contains(3));
myHashSet.add(2);
System.out.println(Arrays.toString(myHashSet.set));
System.out.println(myHashSet.contains(2));
myHashSet.remove(2);
System.out.println(Arrays.toString(myHashSet.set));
System.out.println(myHashSet.contains(2));
}
}
Complexity Analysis:
Time complexity: All opeeration runs in O(1) time, add
LinkedList
remove
contains
106
104
Space complexity: O(1) since we are storing elements into an array of linked lists.
Above implementations source code can be found at