- Design HashMap
Easy
Design a HashMap without using any built-in hash table libraries.
Implement the MyHashMap class:
MyHashMap() initializes the object with an empty map.
void put(int key, int value) inserts a (key, value) pair into the HashMap. If the key already exists in the map, update the corresponding value.
int get(int key) returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key.
void remove(key) removes the key and its corresponding value if the map contains the mapping for the key.
Example 1:
Input
[“MyHashMap”, “put”, “put”, “get”, “get”, “put”, “get”, “remove”, “get”]
[[], [1, 1], [2, 2], [1], [3], [2, 1], [2], [2], [2]]
Output
[null, null, null, 1, -1, null, 1, null, -1]
Explanation
MyHashMap myHashMap = new MyHashMap();
myHashMap.put(1, 1); // The map is now [[1,1]]
myHashMap.put(2, 2); // The map is now [[1,1], [2,2]]
myHashMap.get(1); // return 1, The map is now [[1,1], [2,2]]
myHashMap.get(3); // return -1 (i.e., not found), The map is now [[1,1], [2,2]]
myHashMap.put(2, 1); // The map is now [[1,1], [2,1]] (i.e., update the existing value)
myHashMap.get(2); // return 1, The map is now [[1,1], [2,1]]
myHashMap.remove(2); // remove the mapping for 2, The map is now [[1,1]]
myHashMap.get(2); // return -1 (i.e., not found), The map is now [[1,1]]
Constraints:
0 <= key, value <= 106
At most 104 calls will be made to put, get, and remove.
解法1:用双重vector。
#define HASHTABLE_SIZE 1001
class MyHashMap {
public:
MyHashMap() {
data.resize(HASHTABLE_SIZE, vector<int>());
}
void put(int key, int value) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey].empty()) data[newKey].resize(HASHTABLE_SIZE, -1);
data[newKey][key / HASHTABLE_SIZE] = value;
}
int get(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey].empty()) return -1;
return data[newKey][key / HASHTABLE_SIZE];
}
void remove(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey].empty()) return;
data[newKey][key / HASHTABLE_SIZE] = -1;
}
private:
vector<vector<int>> data;
};
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap* obj = new MyHashMap();
* obj->put(key,value);
* int param_2 = obj->get(key);
* obj->remove(key);
*/
解法2:跟上面差不多,不过是用指针数组实现。
#define HASHTABLE_SIZE 1001
class MyHashMap {
public:
MyHashMap() {
}
void put(int key, int value) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == NULL) {
data[newKey] = (int *)malloc(HASHTABLE_SIZE * sizeof(int));
for (int i = 0; i < HASHTABLE_SIZE; i++) data[newKey][i] = -1;
}
data[newKey][key / HASHTABLE_SIZE] = value;
}
int get(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == NULL) return -1;
return data[newKey][key / HASHTABLE_SIZE];
}
void remove(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == NULL) return;
data[newKey][key / HASHTABLE_SIZE] = -1;
}
private:
int *data[HASHTABLE_SIZE] = {0};
};
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap* obj = new MyHashMap();
* obj->put(key,value);
* int param_2 = obj->get(key);
* obj->remove(key);
*/
解法3:上面的方法都占用了太多空间,实际上没有必要。用new Node,有多少节点才加多少节点。注意加的时候加在链表头上,这样下次访问的时候由于cacht hit更容易早点遇到。
#define HASHTABLE_SIZE 1001
struct Node {
int key;
int value;
Node *next;
Node(int k, int v) : key(k), value(v), next(NULL) {}
};
class MyHashMap {
public:
MyHashMap() {
}
void put(int key, int value) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == nullptr) {
data[newKey] = new Node(key, value);
} else {
Node *head = data[newKey], *p = head;
while (p) {
if (p->key == key) {
p->value = value;
return;
}
p = p->next;
}
Node *newNode = new Node(key, value);
newNode->next = data[newKey];
data[newKey] = newNode;
}
}
int get(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == nullptr) return -1;
Node *head = data[newKey], *p = head;
while (p) {
if (p->key == key) {
return p->value;
}
p = p->next;
}
return -1;
}
void remove(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == nullptr) return;
Node *head = data[newKey];
Node *dummy = new Node(0, 0);
dummy->next = head;
Node *prev = dummy, *p = head;
while (p) {
if (p->key == key) {
prev->next = p->next;
p->value = -1; //It is not necessary here. For remove, the node is actually deleted; set it as -1 to pass the test
//delete(p);
//p = nullptr;
return;
}
p = p->next;
}
//delete(dummy);
//dummy = nullptr;
return;
}
private:
Node *data[HASHTABLE_SIZE] = {NULL};
};
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap* obj = new MyHashMap();
* obj->put(key,value);
* int param_2 = obj->get(key);
* obj->remove(key);
*/
下面的是malloc版本,纯C风格。
#define HASHTABLE_SIZE 1001
struct Node {
int key;
int value;
Node *next;
};
class MyHashMap {
public:
MyHashMap() {
}
void put(int key, int value) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == NULL) {
data[newKey] = (Node *)malloc(sizeof(Node));
data[newKey]->key = key;
data[newKey]->value = value;
data[newKey]->next = NULL;
} else {
Node *head = data[newKey], *p = head;
while (p) {
if (p->key == key) {
p->value = value;
return;
}
p = p->next;
}
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
newNode->next = data[newKey];
data[newKey] = newNode;
}
}
int get(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == NULL) return -1;
Node *head = data[newKey], *p = head;
while (p) {
if (p->key == key) {
return p->value;
}
p = p->next;
}
return -1;
}
void remove(int key) {
int newKey = key % HASHTABLE_SIZE;
if (data[newKey] == NULL) return;
Node *head = data[newKey];
Node *dummy = (Node *)malloc(sizeof(Node));
dummy->next = head;
Node *prev = dummy, *p = head;
while (p) {
if (p->key == key) {
prev->next = p->next;
p->value = -1; //It is not necessary here. For remove, the node is actually deleted; set it as -1 to pass the test
//delete(p);
//p = nullptr;
return;
}
p = p->next;
}
//delete(dummy);
//dummy = nullptr;
return;
}
private:
Node *data[HASHTABLE_SIZE] = {NULL};
};
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap* obj = new MyHashMap();
* obj->put(key,value);
* int param_2 = obj->get(key);
* obj->remove(key);
*/