Description:
Design a HashMap without using any built-in hash table libraries.
To be specific, your design should include these functions:
put(key, value) : Insert a (key, value) pair into the HashMap. If the value already exists in the HashMap, update the value.
get(key): Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key.
remove(key) : Remove the mapping for the value key if this map contains the mapping for the key.
Solution:
思路:和HashMap源码思路一样,HashMap源码
总的来说,就是分配数组,每个数组下面都接一个linkedlist,使用以下代码把key映射到具体的数组中,(该操作保证查询速度为O(1))
int index = Integer.hashCode(key) % array.length;
增删改查的核心功能就是先找到目标数组,在目标数组中遍历单链表。
总体代码如下:
class MyHashMap {
//长度为10000的listNode类型的数组
ListNode[] nodes = new ListNode[10000];
private static class ListNode{
int key, val;
ListNode next;
ListNode(int key, int val){
this.key = key;
this.val = val;
}
}
//find the element just before the target element
private ListNode findElement(int index, int key){
if(nodes[index] == null)
return nodes[index] = new ListNode(-1, -1);
ListNode prev = nodes[index];
while(prev.next != null && prev.next.key != key){
prev = prev.next;
}
return prev;
}
//根据key计算在数组中对应的位置 即index
private int getIndex(int key){
return Integer.hashCode(key) % nodes.length;
}
/** Initialize your data structure here. */
public MyHashMap() {
}
/** value will always be non-negative. */
public void put(int key, int value) {
int index = getIndex(key);
ListNode prev = findElement(index, key);
if(prev.next != null){
prev.next.val = value;
} else {
prev.next = new ListNode(key, value);
}
}
/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
public int get(int key) {
int index = getIndex(key);
ListNode prev = findElement(index, key);
return prev.next == null ? -1 : prev.next.val;
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
public void remove(int key) {
int index = getIndex(key);
ListNode prev = findElement(index, key);
if(prev.next != null)
prev.next = prev.next.next;
}
}
/**
* 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);
*/
总结:java中的HashMap是个面试问烂的问题, 他是线程不安全的,之前的版本多线程下会在链表中产生环,后面的版本强制保证了链表顺序,使得不会产生环。查询速度最好O(1),最坏当变成单链表的情况下O(n)。所以后来版本的JDK使用红黑树代替链表,当链表足够长之后。
如何找出链表中的环,使用快慢指针