leetcode706-Design HashMap

题目

不使用任何内建的哈希表库设计一个哈希映射(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 。
示例:
输入:
[“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
最多调用 104 次 put、get 和 remove 方法

分析

这道题目要求自建一个map,最简单的办法就是通过数组实现,key作为数组的下标,value作为数组元素,这种有个问题在于需要给数组做一遍初始化为一个负数(因为map的value也可能是0),初始化一个10^6的数组还是需要一定的时间的,同时空间复杂度也很大,如果一直没有元素插入进来,就会有这个数组一直占着内存
或者换一个思路,减少空间复杂度的思路一定是链表,新增一个元素给他开一个空间,同时为了减少初始化的遍历时间,我们可以把这个数组的长度设置为1000,也无需任何初始化操作,这样后续肯定会有不同的key命中到相同的索引上,为了解决这个问题,我们把数组的元素类型设置成一个链表结点,链表结点的key是map的key,value是map的value,我们通过一个hash函数来把map的key换算到1000以内保证可以在数组中有对应的索引,这样如果我们的hash函数足够的分散的话,就能保证我们的链表也足够分散,put/get/remove函数的时间复杂度也不会太大。当然极端情况下所有的key都命中到一个链表,那这种情况下就需要遍历这个长链表去插入查询删除元素,这样其实也是非常耗时的

public class MyHashMap {
	Node[] a;
	public class Node{
		int key;
		int value;
		Node next;
		Node(int key,int value){
			this.key = key;
			this.value = value;
			this.next = null;
		}
	}
	public MyHashMap(){
		a = new Node[1000];
	}
	public void put(int key,int value) {
		int hashKey = getHash(key);
		Node head = a[hashKey];
		if(head == null) {
			a[hashKey] = new Node(key,value);
		} else {
			Node pre = null;
			while(head != null) {
				if(head.key ==key) {
					head.value = value;
					return;
				} else {
					pre = head;
					head = head.next;
				}
			}
			pre.next = new Node(key,value);
		}
	}
	public void remove(int key) {
		int hashKey = getHash(key);
		Node head = a[hashKey];
		if(head != null && head.key ==key) {
			a[hashKey] = head.next;
			return;
		}
		Node pre = null;
		while(head != null) {
			if(head.key == key) {
				pre.next = head.next;
				return;
			} else {
				pre = head;
				head = head.next;
			}
		}
	}
	public int get(int key) {
		int hashKey = getHash(key);
		Node head = a[hashKey];
		while(head != null) {
			if(head.key == key) {
				return head.value;
			} else {
				head = head.next;
			}
		}
		return -1;
	}
	public int getHash(int key) {
		int m = Integer.hashCode(key);
		return m / 1000;
	}
}
public class designHashMap {
	public static void main(String[] args) {
		MyHashMap myHashMap = new MyHashMap();
		myHashMap.put(1, 1); // myHashMap 现在为 [[1,1]]
		myHashMap.put(2, 2); // myHashMap 现在为 [[1,1], [2,2]]
		System.out.println(myHashMap.get(1));    // 返回 1 ,myHashMap 现在为 [[1,1], [2,2]]
		System.out.println(myHashMap.get(3));    // 返回 -1(未找到),myHashMap 现在为 [[1,1], [2,2]]
		myHashMap.put(2, 1); // myHashMap 现在为 [[1,1], [2,1]](更新已有的值)
		System.out.println(myHashMap.get(2));    // 返回 1 ,myHashMap 现在为 [[1,1], [2,1]]
		myHashMap.remove(2); // 删除键为 2 的数据,myHashMap 现在为 [[1,1]]
		System.out.println(myHashMap.get(2));    // 返回 -1(未找到),myHashMap 现在为 [[1,1]]
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值