0706. Design HashMap
706. Design HashMap
706. Design HashMap
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.
Example:
MyHashMap hashMap = new MyHashMap(); hashMap.put(1, 1); hashMap.put(2, 2); hashMap.get(1); // returns 1 hashMap.get(3); // returns -1 (not found) hashMap.put(2, 1); // update the existing value hashMap.get(2); // returns 1 hashMap.remove(2); // remove the mapping for 2 hashMap.get(2); // returns -1 (not found)
Note:
All keys and values will be in the range of [0, 1000000]. The number of operations will be in the range of [1, 10000]. Please do not use the built-in HashMap library.
思路
设计一个HashMap的几点:
- 设计一个合适的散列函数;
- 定义装载因子阈值,并且设计动态扩容策略;
- 选择合适的散列冲突解决方法。
工业级的HashMap主要采用链表法,有的库为了优化还采用红黑树。
这里就粗暴的用两个链表来实现。
- 时间复杂度 O(N)
- 空间复杂度 O(N)
代码
use std::cell::RefCell;
use std::rc::{Rc, Weak};
#[derive(Clone, Debug)]
pub struct MyLinkedList {
len: i32,
head: Option<Rc<RefCell<Node>>>,
tail: Option<Rc<RefCell<Node>>>,
}
#[derive(Clone, Debug)]
struct Node {
pub key: i32,
pub val: i32,
pub prev: Option<Weak<RefCell<Node>>>,
pub next: Option<Rc<RefCell<Node>>>,
}
impl Node {
pub fn new(key: i32, val: i32) -> Self {
Node {
key,
val,
prev: None,
next: None,
}
}
}
impl MyLinkedList {
pub fn new() -> Self {
let ret = MyLinkedList {
len: 0,
head: Some(Rc::new(RefCell::new(Node::new(0, 0)))),
tail: Some(Rc::new(RefCell::new(Node::new(0, 0)))),
};
ret.head.as_ref().unwrap().borrow_mut().next = ret.tail.clone();
ret.tail.as_ref().unwrap().borrow_mut().prev = Some(Rc::downgrade(ret.head.as_ref().unwrap()));
ret
}
pub fn push(&mut self, key: i32, val: i32) {
if let Some(p) = self.find_by_key(key) {
p.borrow_mut().val = val;
return;
}
let p = self.tail.clone().unwrap();
let p = p.borrow().prev.as_ref().unwrap().upgrade().clone().unwrap();
let next = p.borrow().next.clone().unwrap();
let prev = p;
let node = Rc::new(RefCell::new(Node::new(key, val)));
node.borrow_mut().prev = Some(Rc::downgrade(&prev));
node.borrow_mut().next = Some(next.clone());
next.borrow_mut().prev = Some(Rc::downgrade(&node));
prev.borrow_mut().next = Some(node);
self.len += 1;
}
#[inline]
fn find_by_key(&self, key: i32) -> Option<Rc<RefCell<Node>>> {
let mut p = self.head.clone().unwrap();
for _ in 0..self.len {
let next = p.borrow().next.clone().unwrap();
p = next;
if p.borrow().key == key {
return Some(p);
}
}
None
}
pub fn get(&self, key: i32) -> i32 {
self.find_by_key(key).map(|p| p.borrow().val).unwrap_or(-1)
}
pub fn remove_by_key(&mut self, key: i32) {
if let Some(p) = self.find_by_key(key) {
let prev = p.borrow().prev.as_ref().unwrap().upgrade().clone().unwrap();
let next = p.borrow().next.clone().unwrap();
prev.borrow_mut().next = Some(next.clone());
next.borrow_mut().prev = Some(Rc::downgrade(&prev));
self.len -= 1;
}
}
}
struct MyHashMap {
map: Vec<Option<MyLinkedList>>,
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl MyHashMap {
/** Initialize your data structure here. */
fn new() -> Self {
Self {
map: vec![None; 1001],
}
}
/** value will always be non-negative. */
fn put(&mut self, key: i32, value: i32) {
let idx = (key % 1001) as usize;
if self.map[idx].is_none() {
self.map[idx] = Some(MyLinkedList::new());
}
self.map[idx].as_mut().unwrap().push(key, value);
}
/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
fn get(&self, key: i32) -> i32 {
let idx = (key % 1001) as usize;
match self.map[idx].as_ref() {
None => -1,
Some(sub_map) => sub_map.get(key)
}
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
fn remove(&mut self, key: i32) {
let idx = (key % 1001) as usize;
if let Some(sub_map) = self.map[idx].as_mut() {
sub_map.remove_by_key(key);
}
}
}
- 执行用时: 36 ms
- 内存消耗: 4.6 MB
题型与相似题
题型
1.哈希表
相似题