diff --git a/705_design_hashset/Cargo.lock b/705_design_hashset/Cargo.lock new file mode 100644 index 0000000..3006eb2 --- /dev/null +++ b/705_design_hashset/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "design_hashset" +version = "0.1.0" diff --git a/705_design_hashset/Cargo.toml b/705_design_hashset/Cargo.toml new file mode 100644 index 0000000..76b9a6f --- /dev/null +++ b/705_design_hashset/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "design_hashset" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/705_design_hashset/src/lib.rs b/705_design_hashset/src/lib.rs new file mode 100644 index 0000000..6eb9b35 --- /dev/null +++ b/705_design_hashset/src/lib.rs @@ -0,0 +1,47 @@ +use std::hash::{DefaultHasher, Hash, Hasher}; + +pub struct MyHashSet { + capacity: usize, + buckets: Vec>, +} + +impl MyHashSet { + pub fn new() -> Self { + const CAPACITY: usize = 4096; + Self { + capacity: CAPACITY, + buckets: vec![Vec::new(); CAPACITY], + } + } + + pub fn add(&mut self, key: i32) { + let index = self.get_bucket_index(key); + let list = self.buckets.get_mut(index).unwrap(); + + if list.iter().find(|num| **num == key).is_none() { + list.push(key); + } + } + + pub fn remove(&mut self, key: i32) { + let index = self.get_bucket_index(key); + let list = self.buckets.get_mut(index).unwrap(); + + if let Some(index_to_remove) = list.iter().position(|num| *num == key) { + list.remove(index_to_remove); + } + } + + pub fn contains(&self, key: i32) -> bool { + let index = self.get_bucket_index(key); + let list = self.buckets.get(index).unwrap(); + + list.iter().find(|num| **num == key).is_some() + } + + fn get_bucket_index(&self, key: impl Hash) -> usize { + let mut hasher = DefaultHasher::new(); + key.hash(&mut hasher); + (hasher.finish() as usize) & (self.capacity - 1) + } +}