LeetCode 706: Design HashMap (Hash设计好题)

  1. 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);
 */

猜你喜欢

转载自blog.csdn.net/roufoo/article/details/128172285
今日推荐