• 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);
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    解法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);
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    解法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);
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    下面的是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);
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
  • 相关阅读:
    如何实现云上 Lakehouse 高性能
    tomcat在idea上的配置
    硬盘分区基础
    docker-compose搭建的mysql,如何定时备份数据
    python基础环境
    论文翻译:2021_Real-Time Denoising and Dereverberation wtih Tiny Recurrent U-Net
    three.js r146动态加载fbx文件,非module模式
    数据库使用psql及jdbc进行远程连接,不定时自动断开的解决办法
    nSoftware.PowerShell.Server.2020
    Matlab|基于多目标粒子群算法的微电网优化调度(多约束多目标智能算法模板)
  • 原文地址:https://blog.csdn.net/roufoo/article/details/128172285