Easy

题目描述

不使用任何内建的哈希表库设计一个哈希映射(HashMap)。

实现 MyHashMap 类:

  • MyHashMap() 用空映射初始化对象
  • void put(int key, int value) 向 HashMap 插入一个键值对 (key, value)。如果 key 已经存在于映射中,则更新其对应的值 value
  • int get(int key) 返回特定的 key 所映射的 value;如果映射中不包含 key 的映射,返回 -1
  • void remove(key) 如果映射中存在 key 的映射,则移除 key 和它所对应的 value

示例 1:

输入:
["MyHashMap", "put", "put", "get", "get", "put", "get", "remove", "get"]
[[], [1, 1], [2, 2], [1], [3], [2, 1], [2], [2], [2]]
输出:
[null, null, null, 1, -1, null, 1, null, -1]

解释:
MyHashMap myHashMap = new MyHashMap();
myHashMap.put(1, 1); // myHashMap 现在为 [[1,1]]
myHashMap.put(2, 2); // myHashMap 现在为 [[1,1], [2,2]]
myHashMap.get(1);    // 返回 1 ,myHashMap 现在为 [[1,1], [2,2]]
myHashMap.get(3);    // 返回 -1(未找到),myHashMap 现在为 [[1,1], [2,2]]
myHashMap.put(2, 1); // myHashMap 现在为 [[1,1], [2,1]](更新已有的值)
myHashMap.get(2);    // 返回 1 ,myHashMap 现在为 [[1,1], [2,1]]
myHashMap.remove(2); // 删除键为 2 的数据,myHashMap 现在为 [[1,1]]
myHashMap.get(2);    // 返回 -1(未找到),myHashMap 现在为 [[1,1]]

提示:

  • 0 <= key, value <= 10^6
  • 最多调用 10^4 次 put、get 和 remove 方法

解题思路

解题思路

设计 HashMap 有多种实现方法:

方法一:数组实现(推荐)

由于题目约束 key 的范围是 0 ≤ key ≤ 10^6,我们可以直接使用一个大数组来存储所有可能的 key-value 对。数组下标就是 key,数组值就是 value。为了区分未设置的值和实际的值,我们可以用 -1 表示未设置。

方法二:链地址法

使用哈希函数将 key 映射到桶数组的某个位置,每个桶用链表存储发生冲突的键值对。这种方法空间效率更高,但实现稍复杂。

方法三:开放地址法

当发生哈希冲突时,寻找下一个可用的位置存储数据。常见的探测方法有线性探测、二次探测等。

考虑到题目的约束条件和实现简单性,我们选择方法一作为主要实现。虽然空间消耗较大,但在给定的数据范围内是可行的,且操作的时间复杂度为 O(1)。

代码实现

class MyHashMap {
private:
    vector<int> data;
    
public:
    MyHashMap() {
        data.resize(1000001, -1);
    }
    
    void put(int key, int value) {
        data[key] = value;
    }
    
    int get(int key) {
        return data[key];
    }
    
    void remove(int key) {
        data[key] = -1;
    }
};
class MyHashMap:

    def __init__(self):
        self.data = [-1] * 1000001

    def put(self, key: int, value: int) -> None:
        self.data[key] = value

    def get(self, key: int) -> int:
        return self.data[key]

    def remove(self, key: int) -> None:
        self.data[key] = -1
public class MyHashMap {
    private int[] data;

    public MyHashMap() {
        data = new int[1000001];
        Array.Fill(data, -1);
    }
    
    public void Put(int key, int value) {
        data[key] = value;
    }
    
    public int Get(int key) {
        return data[key];
    }
    
    public void Remove(int key) {
        data[key] = -1;
    }
}
var MyHashMap = function() {
    this.data = new Array(1000001).fill(-1);
};

MyHashMap.prototype.put = function(key, value) {
    this.data[key] = value;
};

MyHashMap.prototype.get = function(key) {
    return this.data[key];
};

MyHashMap.prototype.remove = function(key) {
    this.data[key] = -1;
};

复杂度分析

操作时间复杂度空间复杂度
初始化O(1)O(max_key)
putO(1)O(1)
getO(1)O(1)
removeO(1)O(1)

其中 max_key = 10^6 是 key 的最大值。这种实现方法牺牲了空间效率来换取时间效率,适合在 key 范围相对较小且已知的场景下使用。

相关题目